summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/cpp_pretty_printer
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/cpp_pretty_printer')
-rw-r--r--ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_1.h583
-rw-r--r--ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_2.h520
-rw-r--r--ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_abstract.h88
3 files changed, 1191 insertions, 0 deletions
diff --git a/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_1.h b/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_1.h
new file mode 100644
index 000000000..668d5049d
--- /dev/null
+++ b/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_1.h
@@ -0,0 +1,583 @@
+// Copyright (C) 2005 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_CPP_PRETTY_PRINTER_KERNEl_1_
+#define DLIB_CPP_PRETTY_PRINTER_KERNEl_1_
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include "cpp_pretty_printer_kernel_abstract.h"
+#include "../algs.h"
+
+namespace dlib
+{
+
+ template <
+ typename stack,
+ typename tok
+ >
+ class cpp_pretty_printer_kernel_1
+ {
+ /*!
+ REQUIREMENTS ON stack
+ must be an implementation of stack/stack_kernel_abstract.h and
+ stack::type == unsigned long
+
+ REQUIREMENTS ON tok
+ must be an implementation of tokenizer/tokenizer_kernel_abstract.h
+
+ INFO
+ This implementation applies a color scheme, turns include directives
+ such as #include "file.h" into links to file.h.html, and it also puts
+ HTML anchor points on function and class declarations.
+ !*/
+
+ public:
+
+ cpp_pretty_printer_kernel_1 (
+ );
+
+ virtual ~cpp_pretty_printer_kernel_1 (
+ );
+
+ void print (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const;
+
+ void print_and_number (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const;
+
+ private:
+
+ const std::string htmlify (
+ const std::string& str
+ ) const;
+ /*!
+ ensures
+ - str == str but with any '<' replaced with '&lt;', any '>' replaced
+ with '&gt;', and any '&' replaced with '&amp;'
+ !*/
+
+ // data members
+ mutable tok t;
+
+ void number (
+ std::istream& in,
+ std::ostream& out
+ ) const;
+ /*!
+ ensures
+ - prints in to out and adds line numbers
+ !*/
+
+ // restricted functions
+ cpp_pretty_printer_kernel_1(const cpp_pretty_printer_kernel_1&); // copy constructor
+ cpp_pretty_printer_kernel_1& operator=(const cpp_pretty_printer_kernel_1&); // assignment operator
+
+ };
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ cpp_pretty_printer_kernel_1<stack,tok>::
+ cpp_pretty_printer_kernel_1 (
+ )
+ {
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ cpp_pretty_printer_kernel_1<stack,tok>::
+ ~cpp_pretty_printer_kernel_1 (
+ )
+ {
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ void cpp_pretty_printer_kernel_1<stack,tok>::
+ print (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const
+ {
+ using namespace std;
+
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_1::print");
+
+ t.set_stream(in);
+
+ out << "<html><!-- "
+ << "Created using the cpp_pretty_printer from the dlib C++ library. See http://dlib.net for updates."
+ << " --><head><title>" << title << "</title></head><body bgcolor='white'><pre>\n";
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_1::print");
+
+ unsigned long scope = 0; // counts the number of new scopes we have entered
+ // since we were at a scope where functions can be declared
+
+ bool recently_seen_class_keyword = false;
+ // true if we have seen the keywords class, struct, or enum and
+ // we have not seen any identifiers or { characters
+
+ bool recently_seen_include = false;
+ // true if we have seen the #include keyword and have not seen double
+ // quoted text or >
+
+ bool recently_seen_new_scope = false;
+ // true if we have seen the keywords class, namespace, or struct and
+ // we have not seen the characters {, ), or ; since then
+
+ bool recently_seen_paren = false;
+ // true if we have seen a ) and we have only seen white_space or comments since
+
+ bool in_initialization_list = false;
+ // true if we have seen a ) followed by any white space or comments and then
+ // followed by a : (in scope==0 with recently_seen_preprocessor==false) and we
+ // have not yet seen the character { or ;
+
+ bool recently_seen_preprocessor = false;
+ // true if we have seen the #pragma or #if or #define or #elif keywords and have
+ // not seen an end of line.
+
+ bool recently_seen_extern = false;
+ // true if we have seen the extern keyword and haven't seen a ; or { yet.
+
+ unsigned long paren_count = 0;
+ // this is the number of ( we have seen minus the number of ) we have
+ // seen.
+
+
+ int type;
+ stack scopes; // a stack to hold old scopes
+ string token, temp;
+ t.get_token(type,token);
+ while (type != tok::END_OF_FILE)
+ {
+ switch (type)
+ {
+ case tok::IDENTIFIER: // ------------------------------------------
+ if ( recently_seen_class_keyword)
+ {
+ // this might be a class name so check if there is a
+ // ; or identifier or * or & coming up.
+ type = t.peek_type();
+ temp.clear();
+ if (type == tok::WHITE_SPACE)
+ {
+ t.get_token(type,temp);
+ if (temp.find_first_of("\n\r") != string::npos)
+ recently_seen_preprocessor = false;
+ }
+ if (t.peek_token() != ";" && t.peek_type() != tok::IDENTIFIER &&
+ t.peek_token() != "*" && t.peek_token() != "&")
+ {
+ // this is the name of a class or struct in a class or
+ // struct declaration.
+ out << "<b><a name='" << token << "'></a>" << token << "</b>" << temp;
+ }
+ else
+ {
+ out << token << temp;
+ }
+ }
+ else if ( !in_initialization_list &&
+ !recently_seen_preprocessor )
+ {
+ // this might be a function name so check if there is a
+ // ( coming up.
+ type = t.peek_type();
+ temp.clear();
+ if (type == tok::WHITE_SPACE)
+ {
+ t.get_token(type,temp);
+ type = t.peek_type();
+ }
+ if (type == tok::OTHER && t.peek_token() == "(")
+ {
+ if (scope == 0 && paren_count == 0)
+ {
+ // this is a function definition or prototype
+ out << "<b><a name='" << token << "'></a>" << token << "</b>" << temp;
+ }
+ else
+ {
+ // this is a function call (probably)
+ out << "<font color='#BB00BB'>" << token << "</font>" << temp;
+ }
+ }
+ else
+ {
+ out << token << temp;
+ }
+ }
+ else
+ {
+ out << token;
+ }
+
+
+
+ recently_seen_class_keyword = false;
+ recently_seen_paren = false;
+ break;
+
+ case tok::KEYWORD: // ---------------------------------------------
+ if (scope == 0 && token == "operator")
+ {
+ // Doing this is sort of weird since operator is really a keyword
+ // but I just like how this looks.
+ out << "<b><a name='" << token << "'></a>" << token << "</b>";
+ }
+ // this isn't a keyword if it is something like #include <new>
+ else if ( token == "true" || token == "false")
+ {
+ // color 'true' and 'false' the same way we color numbers
+ out << "<font color='#979000'>" << token << "</font>";
+ }
+ else if (!recently_seen_include)
+ {
+ // This is a normal keyword
+ if (token == "char" || token == "unsigned" || token == "signed" ||
+ token == "short" || token == "int" || token == "long" ||
+ token == "float" || token == "double" || token == "bool" ||
+ token == "void" || token == "size_t" || token == "wchar_t")
+ {
+ out << "<font color='#0000FF'><u>" << token << "</u></font>";
+ }
+ else
+ {
+ out << "<font color='#0000FF'>" << token << "</font>";
+ }
+ }
+ else
+ {
+ out << token;
+ }
+
+ if (token == "#include")
+ {
+ recently_seen_include = true;
+ }
+ else if (token == "class")
+ {
+ recently_seen_new_scope = true;
+ recently_seen_class_keyword = true;
+ }
+ else if (token == "namespace")
+ {
+ recently_seen_new_scope = true;
+ }
+ else if (token == "enum")
+ {
+ recently_seen_class_keyword = true;
+ }
+ else if (token == "struct")
+ {
+ recently_seen_new_scope = true;
+ recently_seen_class_keyword = true;
+ }
+ else if (token == "#pragma" || token == "#if" || token == "#define" || token == "#elif")
+ {
+ recently_seen_preprocessor = true;
+ }
+ else if (token == "extern")
+ {
+ recently_seen_extern = true;
+ }
+ recently_seen_paren = false;
+ break;
+
+ case tok::COMMENT: // ---------------------------------------------
+ {
+ // if this is a special anchor comment
+ if (token.size() > 4 &&
+ token[0] == '/' &&
+ token[1] == '*' &&
+ token[2] == '!' &&
+ token[3] == 'A' &&
+ token[4] == ' '
+ )
+ {
+ temp = token;
+ istringstream sin(token);
+ sin >> temp;
+ sin >> temp;
+ sin.get();
+ // if there was still more stuff in the token then we are ok.
+ if (sin)
+ out << "<a name='" << temp << "'/>";
+ }
+ out << "<font color='#009900'>" << htmlify(token) << "</font>";
+ }
+ break;
+
+ case tok::SINGLE_QUOTED_TEXT: // ----------------------------------
+ {
+ out << "<font color='#FF0000'>" << htmlify(token) << "</font>";
+ recently_seen_paren = false;
+ }
+ break;
+
+ case tok::NUMBER: // -----------------------------------------
+ {
+ out << "<font color='#979000'>" << token << "</font>";
+ recently_seen_include = false;
+ }
+ break;
+
+ case tok::WHITE_SPACE: // -----------------------------------------
+ {
+ out << token;
+ if (token.find_first_of("\n\r") != string::npos)
+ recently_seen_preprocessor = false;
+ }
+ break;
+
+ case tok::DOUBLE_QUOTED_TEXT: // ----------------------------------
+ {
+ if (recently_seen_include)
+ {
+ // this is the name of an included file
+ recently_seen_include = false;
+ out << "<a style='text-decoration:none' href='" << htmlify(token) << ".html'>" << htmlify(token) << "</a>";
+ }
+ else
+ {
+ // this is just a normal quoted string
+ out << "<font color='#CC0000'>" << htmlify(token) << "</font>";
+ }
+ recently_seen_paren = false;
+ }
+ break;
+
+ case tok::OTHER: // -----------------------------------------------
+ switch (token[0])
+ {
+ case '{':
+ out << "<b>{</b>";
+ // if we are entering a new scope
+ if (recently_seen_new_scope || recently_seen_extern)
+ {
+ recently_seen_new_scope = false;
+ scopes.push(scope);
+ scope = 0;
+ }
+ else
+ {
+ ++scope;
+ }
+ in_initialization_list = false;
+ recently_seen_paren = false;
+ recently_seen_class_keyword = false;
+ recently_seen_extern = false;
+ break;
+ case '}':
+ out << "<b>}</b>";
+ if (scope > 0)
+ {
+ --scope;
+ }
+ else if (scopes.size())
+ {
+ scopes.pop(scope);
+ }
+ recently_seen_paren = false;
+ break;
+
+ case ':':
+ out << ':';
+ if (recently_seen_paren && scope == 0 &&
+ recently_seen_preprocessor == false)
+ {
+ in_initialization_list = true;
+ }
+ recently_seen_paren = false;
+ break;
+
+ case ';':
+ out << ';';
+ recently_seen_new_scope = false;
+ recently_seen_paren = false;
+ recently_seen_extern = false;
+ break;
+
+ case ')':
+ out << "<font face='Lucida Console'>)</font>";
+ recently_seen_paren = true;
+ recently_seen_new_scope = false;
+ --paren_count;
+ break;
+
+ case '(':
+ out << "<font face='Lucida Console'>(</font>";
+ recently_seen_paren = false;
+ ++paren_count;
+ break;
+
+ case '>':
+ recently_seen_include = false;
+ out << "<font color='#5555FF'>&gt;</font>";
+ recently_seen_paren = false;
+ break;
+
+ case '<':
+ out << "<font color='#5555FF'>&lt;</font>";
+ recently_seen_paren = false;
+ break;
+
+ case '&':
+ out << "<font color='#5555FF'>&amp;</font>";
+ recently_seen_paren = false;
+ break;
+
+ case '=':
+ case '+':
+ case '-':
+ case '/':
+ case '*':
+ case '!':
+ case '|':
+ case '%':
+ out << "<font color='#5555FF'>" << token << "</font>";
+ recently_seen_paren = false;
+ break;
+
+ default:
+ out << token;
+ recently_seen_paren = false;
+ break;
+
+ } // switch (token[0])
+ break;
+
+ } // switch (type)
+
+ t.get_token(type,token);
+ } // while (type != tok::END_OF_FILE)
+
+
+ out << "\n</pre></body></html>";
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_1::print");
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ void cpp_pretty_printer_kernel_1<stack,tok>::
+ print_and_number (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const
+ {
+ using namespace std;
+ ostringstream sout;
+ print(in,sout,title);
+ istringstream sin(sout.str());
+ number(sin,out);
+ }
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // private member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ void cpp_pretty_printer_kernel_1<stack,tok>::
+ number (
+ std::istream& in,
+ std::ostream& out
+ ) const
+ {
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_1::number");
+
+ std::string space = "&nbsp;&nbsp;&nbsp;";
+ std::ios::int_type ch;
+ unsigned long count = 1;
+ while ((ch=in.get()) != EOF)
+ {
+ if (ch != '\n')
+ {
+ out << (char)ch;
+ }
+ else
+ {
+ out << "\n<font color='555555'>" << count << " </font> " + space;
+ ++count;
+ if (count == 10)
+ space = "&nbsp;&nbsp;";
+ if (count == 100)
+ space = "&nbsp;";
+ if (count == 1000)
+ space = "";
+ }
+ }
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_1::number");
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ const std::string cpp_pretty_printer_kernel_1<stack,tok>::
+ htmlify (
+ const std::string& str
+ ) const
+ {
+ std::string::size_type i;
+ std::string temp;
+ for (i = 0; i < str.size(); ++i)
+ {
+ if (str[i] == '<')
+ temp += "&lt;";
+ else if (str[i] == '>')
+ temp += "&gt;";
+ else if (str[i] == '&')
+ temp += "&amp;";
+ else
+ temp += str[i];
+ }
+ return temp;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_CPP_PRETTY_PRINTER_KERNEl_1_
+
diff --git a/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_2.h b/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_2.h
new file mode 100644
index 000000000..5ac894b33
--- /dev/null
+++ b/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_2.h
@@ -0,0 +1,520 @@
+// Copyright (C) 2005 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_CPP_PRETTY_PRINTER_KERNEl_2_
+#define DLIB_CPP_PRETTY_PRINTER_KERNEl_2_
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include "cpp_pretty_printer_kernel_abstract.h"
+#include "../algs.h"
+
+namespace dlib
+{
+
+ template <
+ typename stack,
+ typename tok
+ >
+ class cpp_pretty_printer_kernel_2
+ {
+ /*!
+ REQUIREMENTS ON stack
+ must be an implementation of stack/stack_kernel_abstract.h and
+ stack::type == unsigned long
+
+ REQUIREMENTS ON tok
+ must be an implementation of tokenizer/tokenizer_kernel_abstract.h
+
+ INFO
+ This implementation applies a black and white color scheme suitable
+ for printing on a black and white printer. It also places the document
+ title prominently at the top of the pretty printed source file.
+ !*/
+
+ public:
+
+ cpp_pretty_printer_kernel_2 (
+ );
+
+ virtual ~cpp_pretty_printer_kernel_2 (
+ );
+
+ void print (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const;
+
+ void print_and_number (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const;
+
+ private:
+
+ // data members
+ mutable tok t;
+
+ const std::string htmlify (
+ const std::string& str
+ ) const;
+ /*!
+ ensures
+ - str == str but with any '<' replaced with '&lt;', any '>' replaced
+ with '&gt;', and any '&' replaced with '&amp;'
+ !*/
+
+ void number (
+ std::istream& in,
+ std::ostream& out
+ ) const;
+ /*!
+ ensures
+ - prints in to out and adds line numbers
+ !*/
+
+ // restricted functions
+ cpp_pretty_printer_kernel_2(const cpp_pretty_printer_kernel_2&); // copy constructor
+ cpp_pretty_printer_kernel_2& operator=(const cpp_pretty_printer_kernel_2&); // assignment operator
+
+ };
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ cpp_pretty_printer_kernel_2<stack,tok>::
+ cpp_pretty_printer_kernel_2 (
+ )
+ {
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ cpp_pretty_printer_kernel_2<stack,tok>::
+ ~cpp_pretty_printer_kernel_2 (
+ )
+ {
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ void cpp_pretty_printer_kernel_2<stack,tok>::
+ print (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const
+ {
+ using namespace std;
+
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_2::print");
+
+ t.set_stream(in);
+
+ out << "<html><!-- "
+ << "Created using the cpp_pretty_printer from the dlib C++ library. See http://dlib.net for updates."
+ << " --><head>"
+ << "<title>" << title << "</title></head><body bgcolor='white'>"
+ << "<h1><center>" << title << "</center></h1><pre>\n"
+ << "<font style='font-size:9pt' face='Lucida Console'>\n";
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_2::print");
+
+ unsigned long scope = 0; // counts the number of new scopes we have entered
+ // since we were at a scope where functions can be declared
+
+ bool recently_seen_class_keyword = false;
+ // true if we have seen the keywords class or struct and
+ // we have not seen any identifiers or { characters
+
+ bool recently_seen_include = false;
+ // true if we have seen the #include keyword and have not seen double
+ // quoted text or >
+
+ bool recently_seen_new_scope = false;
+ // true if we have seen the keywords class, namespace, or struct and
+ // we have not seen the characters {, ), or ; since then
+
+ bool recently_seen_paren = false;
+ // true if we have seen a ) and we have only seen white_space or comments since
+
+ bool in_initialization_list = false;
+ // true if we have seen a ) followed by any white space or comments and then
+ // followed by a : (in scope==0 with recently_seen_preprocessor==false) and we
+ // have not yet seen the character { or ;
+
+ bool recently_seen_preprocessor = false;
+ // true if we have seen the #pragma or #if or #define or #elif keyword and
+ // have not seen an identifier.
+
+
+ bool recently_seen_extern = false;
+ // true if we have seen the extern keyword and haven't yet seen a
+ // { or ; character.
+
+ unsigned long paren_count = 0;
+ // this is the number of ( we have seen minus the number of ) we have
+ // seen.
+
+
+ int type;
+ stack scopes; // a stack to hold old scopes
+ string token, temp;
+ t.get_token(type,token);
+ while (type != tok::END_OF_FILE)
+ {
+ switch (type)
+ {
+ case tok::IDENTIFIER: // ------------------------------------------
+ if ( recently_seen_class_keyword)
+ {
+ // this might be a class name so check if there is a
+ // ; or identifier or * or &amp; coming up.
+ type = t.peek_type();
+ temp.clear();
+ if (type == tok::WHITE_SPACE)
+ {
+ t.get_token(type,temp);
+ if (temp.find_first_of("\n\r") != string::npos)
+ recently_seen_preprocessor = false;
+ }
+ if (t.peek_token() != ";" && t.peek_type() != tok::IDENTIFIER &&
+ t.peek_token() != "*" && t.peek_token() != "&amp;")
+ {
+ // this is the name of a class or struct in a class or
+ // struct declaration.
+ out << "<b><i>" << token << "</i></b>" << temp;
+ }
+ else
+ {
+ out << token << temp;
+ }
+ }
+ else if ( !in_initialization_list &&
+ !recently_seen_preprocessor &&
+ scope == 0 &&
+ paren_count == 0)
+ {
+ // this might be a function name so check if there is a
+ // ( coming up.
+ type = t.peek_type();
+ temp.clear();
+ if (type == tok::WHITE_SPACE)
+ {
+ t.get_token(type,temp);
+ type = t.peek_type();
+ }
+ if (type == tok::OTHER && t.peek_token() == "(")
+ {
+ // this is a function definition or prototype
+ out << "<b><i>" << token << "</i></b>" << temp;
+ }
+ else
+ {
+ out << token << temp;
+ }
+ }
+ else
+ {
+ out << token;
+ }
+
+
+
+ recently_seen_class_keyword = false;
+ recently_seen_paren = false;
+ break;
+
+ case tok::KEYWORD: // ---------------------------------------------
+ if (scope == 0 && token == "operator")
+ {
+ // Doing this is sort of weird since operator is really a keyword
+ // but I just like how this looks.
+ out << "<b><i>" << token << "</i></b>";
+ }
+ // this isn't a keyword if it is something like #include <new>
+ else if (!recently_seen_include)
+ {
+ // This is a normal keyword
+ out << "<u><font face='Fixedsys'>" << token << "</font></u>";
+ }
+ else
+ {
+ out << token;
+ }
+
+ if (token == "#include")
+ {
+ recently_seen_include = true;
+ }
+ else if (token == "class")
+ {
+ recently_seen_new_scope = true;
+ recently_seen_class_keyword = true;
+ }
+ else if (token == "namespace")
+ {
+ recently_seen_new_scope = true;
+ }
+ else if (token == "struct")
+ {
+ recently_seen_new_scope = true;
+ recently_seen_class_keyword = true;
+ }
+ else if (token == "#pragma" || token == "#define" || token == "#elif" || token == "#if")
+ {
+ recently_seen_preprocessor = true;
+ }
+ else if (token == "extern")
+ {
+ recently_seen_extern = true;
+ }
+ recently_seen_paren = false;
+ break;
+
+ case tok::COMMENT: // ---------------------------------------------
+ {
+ out << "<font face='Courier New'>" << htmlify(token) << "</font>";
+ }
+ break;
+
+ case tok::SINGLE_QUOTED_TEXT: // ----------------------------------
+ {
+ out << htmlify(token);
+ recently_seen_paren = false;
+ }
+ break;
+
+ case tok::WHITE_SPACE: // -----------------------------------------
+ {
+ out << token;
+ if (token.find_first_of("\n\r") != string::npos)
+ recently_seen_preprocessor = false;
+ }
+ break;
+
+ case tok::DOUBLE_QUOTED_TEXT: // ----------------------------------
+ {
+ out << htmlify(token);
+ recently_seen_paren = false;
+ recently_seen_include = false;
+ }
+ break;
+
+ case tok::NUMBER:
+ case tok::OTHER: // -----------------------------------------------
+ switch (token[0])
+ {
+ case '{':
+ out << "<b>{</b>";
+ // if we are entering a new scope
+ if (recently_seen_new_scope || recently_seen_extern)
+ {
+ recently_seen_new_scope = false;
+ scopes.push(scope);
+ scope = 0;
+ }
+ else
+ {
+ ++scope;
+ }
+ in_initialization_list = false;
+ recently_seen_paren = false;
+ recently_seen_class_keyword = false;
+ recently_seen_extern = false;
+ break;
+ case '}':
+ out << "<b>}</b>";
+ if (scope > 0)
+ {
+ --scope;
+ }
+ else if (scopes.size())
+ {
+ scopes.pop(scope);
+ }
+ recently_seen_paren = false;
+ break;
+
+ case ':':
+ out << ':';
+ if (recently_seen_paren && scope == 0 &&
+ recently_seen_preprocessor == false)
+ {
+ in_initialization_list = true;
+ }
+ recently_seen_paren = false;
+ break;
+
+ case ';':
+ out << ';';
+ recently_seen_new_scope = false;
+ recently_seen_paren = false;
+ recently_seen_extern = false;
+ break;
+
+ case ')':
+ out << ')';
+ recently_seen_paren = true;
+ recently_seen_new_scope = false;
+ --paren_count;
+ break;
+
+ case '(':
+ out << '(';
+ recently_seen_paren = false;
+ ++paren_count;
+ break;
+
+ case '>':
+ recently_seen_include = false;
+ out << "&gt;";
+ recently_seen_paren = true;
+ break;
+
+ case '<':
+ out << "&lt;";
+ recently_seen_paren = true;
+ break;
+
+ case '&':
+ out << "&amp;";
+ recently_seen_paren = true;
+ break;
+
+ default:
+ out << token;
+ recently_seen_paren = false;
+ if (token == "&gt;")
+ recently_seen_include = false;
+ break;
+
+ } // switch (token[0])
+ break;
+
+ } // switch (type)
+
+ t.get_token(type,token);
+ } // while (type != tok::END_OF_FILE)
+
+
+ out << "</font></pre></body></html>";
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_2::print");
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ void cpp_pretty_printer_kernel_2<stack,tok>::
+ print_and_number (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const
+ {
+ using namespace std;
+ ostringstream sout;
+ print(in,sout,title);
+ istringstream sin(sout.str());
+ number(sin,out);
+ }
+
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+ // private member function definitions
+// ----------------------------------------------------------------------------------------
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ void cpp_pretty_printer_kernel_2<stack,tok>::
+ number (
+ std::istream& in,
+ std::ostream& out
+ ) const
+ {
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_2::number");
+
+ std::string space = "&nbsp;&nbsp;&nbsp;";
+ std::ios::int_type ch;
+ unsigned long count = 1;
+ while ((ch=in.get()) != EOF)
+ {
+ if (ch != '\n')
+ {
+ out << (char)ch;
+ }
+ else
+ {
+ out << "\n<i><font face='Courier New'>" << count << " </font></i> " + space;
+ ++count;
+ if (count == 10)
+ space = "&nbsp;&nbsp;";
+ if (count == 100)
+ space = "&nbsp;";
+ if (count == 1000)
+ space = "";
+ }
+ }
+ if (!out)
+ throw std::ios::failure("error occurred in cpp_pretty_printer_kernel_2::number");
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ template <
+ typename stack,
+ typename tok
+ >
+ const std::string cpp_pretty_printer_kernel_2<stack,tok>::
+ htmlify (
+ const std::string& str
+ ) const
+ {
+ std::string::size_type i;
+ std::string temp;
+ for (i = 0; i < str.size(); ++i)
+ {
+ if (str[i] == '<')
+ temp += "&lt;";
+ else if (str[i] == '>')
+ temp += "&gt;";
+ else if (str[i] == '&')
+ temp += "&amp;";
+ else
+ temp += str[i];
+ }
+ return temp;
+ }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_CPP_PRETTY_PRINTER_KERNEl_2_
+
diff --git a/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_abstract.h b/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_abstract.h
new file mode 100644
index 000000000..7d572d4fd
--- /dev/null
+++ b/ml/dlib/dlib/cpp_pretty_printer/cpp_pretty_printer_kernel_abstract.h
@@ -0,0 +1,88 @@
+// Copyright (C) 2005 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#undef DLIB_CPP_PRETTY_PRINTER_KERNEl_ABSTRACT_
+#ifdef DLIB_CPP_PRETTY_PRINTER_KERNEl_ABSTRACT_
+
+#include <string>
+#include <ioswfd>
+
+namespace dlib
+{
+
+ class cpp_pretty_printer
+ {
+ /*!
+ INITIAL VALUE
+ This object does not have any state associated with it.
+
+ WHAT THIS OBJECT REPRESENTS
+ This object represents an HTML pretty printer for C++ source code.
+
+ !*/
+
+ public:
+
+ cpp_pretty_printer (
+ );
+ /*!
+ ensures
+ - #*this is properly initialized
+ throws
+ - std::bad_alloc
+ !*/
+
+ virtual ~cpp_pretty_printer (
+ );
+ /*!
+ ensures
+ - any resources associated with *this have been released
+ !*/
+
+ void print (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const;
+ /*!
+ ensures
+ - treats data from in as C++ source code and pretty prints it in
+ HTML and writes it to out.
+ - The title of the HTML document writen to out will be title
+ throws
+ - std::ios_base::failure
+ If there was a problem writing to out then this exception will
+ be thrown.
+ - any other exception
+ This exception may be thrown if there is any other problem.
+ !*/
+
+ void print_and_number (
+ std::istream& in,
+ std::ostream& out,
+ const std::string& title
+ ) const;
+ /*!
+ ensures
+ - treats data from in as C++ source code and pretty prints it in
+ HTML with line numbers and writes it to out.
+ - The title of the HTML document writen to out will be title
+ throws
+ - std::ios_base::failure
+ If there was a problem writing to out then this exception will
+ be thrown.
+ - any other exception
+ This exception may be thrown if there is any other problem.
+ !*/
+
+ private:
+
+ // restricted functions
+ cpp_pretty_printer(const cpp_pretty_printer&); // copy constructor
+ cpp_pretty_printer& operator=(const cpp_pretty_printer&); // assignment operator
+
+ };
+
+}
+
+#endif // DLIB_CPP_PRETTY_PRINTER_KERNEl_ABSTRACT_
+