aboutsummaryrefslogtreecommitdiff
path: root/brep
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-04-21 16:05:13 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-04-21 16:05:13 +0200
commit2a0f39b29c1bea6a4497c0f1826052ffa453af9e (patch)
tree283f6bf1569c1b9f00b6e25fe986ccfff8a8629f /brep
parentc6b4d6c6489731eedba606d3c85c4319c4478b50 (diff)
Move module implementation from brep/ to mod/
Diffstat (limited to 'brep')
-rw-r--r--brep/.gitignore2
-rw-r--r--brep/buildfile59
-rw-r--r--brep/database26
-rw-r--r--brep/database-module55
-rw-r--r--brep/database-module.cxx50
-rw-r--r--brep/database.cxx60
-rw-r--r--brep/diagnostics306
-rw-r--r--brep/diagnostics.cxx30
-rw-r--r--brep/mod-package-details42
-rw-r--r--brep/mod-package-details.cxx257
-rw-r--r--brep/mod-package-search42
-rw-r--r--brep/mod-package-search.cxx181
-rw-r--r--brep/mod-package-version-details45
-rw-r--r--brep/mod-package-version-details.cxx319
-rw-r--r--brep/mod-repository-details42
-rw-r--r--brep/mod-repository-details.cxx146
-rw-r--r--brep/mod-repository-root60
-rw-r--r--brep/mod-repository-root.cxx263
-rw-r--r--brep/module201
-rw-r--r--brep/module.cxx410
-rw-r--r--brep/options-types32
-rw-r--r--brep/options.cli211
-rw-r--r--brep/page402
-rw-r--r--brep/page.cxx693
-rw-r--r--brep/services.cxx15
-rw-r--r--brep/types-parsers57
-rw-r--r--brep/types-parsers.cxx114
27 files changed, 4 insertions, 4116 deletions
diff --git a/brep/.gitignore b/brep/.gitignore
index 852a40d..687b168 100644
--- a/brep/.gitignore
+++ b/brep/.gitignore
@@ -1,5 +1,3 @@
-options
-options.?xx
package-odb*
package.sql
package-extra
diff --git a/brep/buildfile b/brep/buildfile
index 4caf93a..529916a 100644
--- a/brep/buildfile
+++ b/brep/buildfile
@@ -2,16 +2,10 @@
# copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-define mod: libso
-mod{*}: bin.libprefix = mod_
-mod{*}: install = libexec
-
define sql: file
sql{*}: extension = sql
sql{*}: install = data
-./: lib{brep} mod{brep} sql{package package-extra}
-
# lib{brep}
#
import libs += libodb%lib{odb}
@@ -28,57 +22,12 @@ lib{brep}: \
{hxx }{ types } \
{hxx }{ utility } \
{hxx }{ version } \
-$libs
+{hxx }{ wrapper-traits } \
+$libs \
+sql{package package-extra}
-libso{brep}: cxx.export.poptions = -I$out_root -I$src_root
+lib{brep}: cxx.export.poptions = -I$out_root -I$src_root
# Install into the brep/ subdirectory of, say, /usr/include/.
#
install.include = $install.include/brep
-
-# mod{brep}
-#
-import libs += libstudxml%lib{studxml}
-
-gen = {hxx ixx cxx}{ options }
-src = \
- {hxx cxx}{ database } \
- {hxx cxx}{ database-module } \
- {hxx cxx}{ diagnostics } \
- {hxx cxx}{ mod-package-details } \
- {hxx cxx}{ mod-package-search } \
- {hxx cxx}{ mod-package-version-details } \
- {hxx cxx}{ mod-repository-details } \
- {hxx cxx}{ mod-repository-root } \
- {hxx cxx}{ module } \
- {hxx }{ options-types } \
- {hxx cxx}{ page } \
- { cxx}{ services } \
- {hxx cxx}{ types-parsers } \
- {hxx }{ wrapper-traits } \
- ../web/{hxx cxx}{ mime-url-encoding } \
- ../web/{hxx }{ module } \
- ../web/{hxx }{ xhtml } \
- ../web/{hxx cxx}{ xhtml-fragment } \
-../web/apache/{hxx }{ log } \
-../web/apache/{hxx ixx cxx}{ request } \
-../web/apache/{hxx txx cxx}{ service } \
-../web/apache/{hxx }{ stream }
-
-mod{brep}: $src $gen lib{brep} $libs
-
-# Don't install any of the mod{brep} headers.
-#
-$out_base/{$gen}: install = false
-$src_base/{$src}: install = false
-
-# Set option prefix to the empty value to handle all unknown request parameters
-# uniformly with a single catch block.
-#
-cli.options += --std c++11 -I $src_root --include-with-brackets \
---include-prefix brep --guard-prefix BREP \
---cxx-prologue "#include <brep/types-parsers>" \
---cli-namespace brep::cli --generate-file-scanner --suppress-usage \
---generate-modifier --generate-description --option-prefix ""
-
-{hxx ixx cxx}{options}: cli{options}
diff --git a/brep/database b/brep/database
deleted file mode 100644
index d29d4a5..0000000
--- a/brep/database
+++ /dev/null
@@ -1,26 +0,0 @@
-// file : brep/database -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_DATABASE
-#define BREP_DATABASE
-
-#include <odb/forward.hxx> // database
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/options>
-
-namespace brep
-{
- // Returns pointer to the shared database instance, creating one on the
- // first call. On subsequent calls ensures passed host and port equals
- // to ones of the existing database instance throwing runtime_error
- // otherwise. Is not thread-safe.
- //
- shared_ptr<odb::core::database>
- shared_database (const options::db&);
-}
-
-#endif // BREP_DATABASE
diff --git a/brep/database-module b/brep/database-module
deleted file mode 100644
index 64d5aaf..0000000
--- a/brep/database-module
+++ /dev/null
@@ -1,55 +0,0 @@
-// file : brep/database-module -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_DATABASE_MODULE
-#define BREP_DATABASE_MODULE
-
-#include <odb/forward.hxx> // database
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/module>
-#include <brep/options>
-
-namespace brep
-{
- // A module that utilises the database. Specifically, it will retry the
- // request in the face of recoverable database failures (deadlock, loss of
- // connection, etc) up to a certain number of times.
- //
- class database_module: public module
- {
- protected:
- database_module () = default;
-
- // Create a shallow copy (handling instance) if initialized and a deep
- // copy (context exemplar) otherwise.
- //
- explicit
- database_module (const database_module&);
-
- // Required to avoid getting warning from clang that
- // database_module::init() hides module::init() virtual functions. This
- // way all functions get to the same scope and become overloaded set.
- //
- using module::init;
-
- void
- init (const options::db&);
-
- virtual bool
- handle (request&, response&) = 0;
-
- protected:
- size_t retry_;
- shared_ptr<odb::core::database> db_;
-
- private:
- virtual bool
- handle (request&, response&, log&);
- };
-}
-
-#endif // BREP_DATABASE_MODULE
diff --git a/brep/database-module.cxx b/brep/database-module.cxx
deleted file mode 100644
index 630fd89..0000000
--- a/brep/database-module.cxx
+++ /dev/null
@@ -1,50 +0,0 @@
-// file : brep/database-module.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/database-module>
-
-#include <odb/exceptions.hxx>
-
-#include <brep/options>
-#include <brep/database>
-
-namespace brep
-{
- // While currently the user-defined copy constructor is not required (we
- // don't need to deep copy nullptr's), it is a good idea to keep the
- // placeholder ready for less trivial cases.
- //
- database_module::
- database_module (const database_module& r)
- : module (r),
- retry_ (r.retry_),
- db_ (r.initialized_ ? r.db_ : nullptr)
- {
- }
-
- void database_module::
- init (const options::db& o)
- {
- retry_ = o.db_retry ();
- db_ = shared_database (o);
- }
-
- bool database_module::
- handle (request& rq, response& rs, log& l)
- try
- {
- return module::handle (rq, rs, l);
- }
- catch (const odb::recoverable& e)
- {
- if (retry_-- > 0)
- {
- MODULE_DIAG;
- l1 ([&]{trace << e.what () << "; " << retry_ + 1 << " retries left";});
- throw retry ();
- }
-
- throw;
- }
-}
diff --git a/brep/database.cxx b/brep/database.cxx
deleted file mode 100644
index 4b56c37..0000000
--- a/brep/database.cxx
+++ /dev/null
@@ -1,60 +0,0 @@
-// file : brep/database.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/database>
-
-#include <map>
-
-#include <odb/pgsql/database.hxx>
-#include <odb/pgsql/connection-factory.hxx>
-
-namespace brep
-{
- namespace options
- {
- bool
- operator< (const db& x, const db& y)
- {
- int r;
- if ((r = x.db_user ().compare (y.db_user ())) != 0 ||
- (r = x.db_password ().compare (y.db_password ())) != 0 ||
- (r = x.db_name ().compare (y.db_name ())) != 0 ||
- (r = x.db_host ().compare (y.db_host ())))
- return r < 0;
-
- return x.db_port () < y.db_port ();
- }
- }
-
- using namespace odb;
-
- shared_ptr<database>
- shared_database (const options::db& o)
- {
- static std::map<options::db, weak_ptr<database>> databases;
-
- auto i (databases.find (o));
- if (i != databases.end ())
- {
- if (shared_ptr<database> d = i->second.lock ())
- return d;
- }
-
- unique_ptr<pgsql::connection_factory>
- f (new pgsql::connection_pool_factory (o.db_max_connections ()));
-
- shared_ptr<database> d (
- make_shared<pgsql::database> (
- o.db_user (),
- o.db_password (),
- o.db_name (),
- o.db_host (),
- o.db_port (),
- "options='-c default_transaction_isolation=serializable'",
- move (f)));
-
- databases[o] = d;
- return d;
- }
-}
diff --git a/brep/diagnostics b/brep/diagnostics
deleted file mode 100644
index b5b1b36..0000000
--- a/brep/diagnostics
+++ /dev/null
@@ -1,306 +0,0 @@
-// file : brep/diagnostics -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_DIAGNOSTICS
-#define BREP_DIAGNOSTICS
-
-#include <sstream>
-
-#include <brep/types>
-#include <brep/utility>
-
-namespace brep
-{
- struct location
- {
- location (): line (0), column (0) {}
- location (string f, uint64_t l, uint64_t c)
- : file (move (f)), line (l), column (c) {}
-
- string file;
- uint64_t line;
- uint64_t column;
- };
-
- enum class severity {error, warning, info, trace};
-
- struct diag_entry
- {
- severity sev;
- const char* name {nullptr}; // E.g., a function name in tracing.
- location loc;
- string msg;
- };
-
- using diag_data = vector<diag_entry>;
-
- //
- //
- template <typename> struct diag_prologue;
- template <typename> struct diag_mark;
-
- using diag_epilogue = function<void (diag_data&&)>;
-
- struct diag_record
- {
- template <typename T>
- friend const diag_record&
- operator<< (const diag_record& r, const T& x)
- {
- r.os_ << x;
- return r;
- }
-
- diag_record () = default;
-
- template <typename B>
- explicit
- diag_record (const diag_prologue<B>& p) {*this << p;} // See below.
-
- template <typename B>
- explicit
- diag_record (const diag_mark<B>& m) {*this << m;} // See below.
-
- ~diag_record () noexcept(false);
-
- void
- append (const diag_epilogue& e) const
- {
- if (epilogue_ == nullptr) // Keep the first epilogue (think 'fail').
- epilogue_ = &e;
-
- if (!data_.empty ())
- {
- data_.back ().msg = os_.str ();
-
- // Reset the stream. There got to be a more efficient way to do it.
- //
- os_.clear ();
- os_.str ("");
- }
-
- data_.push_back (diag_entry ());
- }
-
- diag_entry&
- current () const {return data_.back ();}
-
- // Move constructible-only type.
- //
- /*
- @@ libstdc++ doesn't yet have the ostringstream move support.
-
- diag_record (diag_record&& r)
- : data_ (move (r.data_)), os_ (move (r.os_))
- {
- epilogue_ = r.epilogue_;
- r.data_.clear (); // Empty.
- }
- */
-
- diag_record (diag_record&& r): data_ (move (r.data_))
- {
- if (!data_.empty ())
- os_ << r.os_.str ();
-
- epilogue_ = r.epilogue_;
- r.data_.clear (); // Empty.
- }
-
- diag_record& operator= (diag_record&&) = delete;
-
- diag_record (const diag_record&) = delete;
- diag_record& operator= (const diag_record&) = delete;
-
- private:
- mutable diag_data data_;
- mutable std::ostringstream os_;
- mutable const diag_epilogue* epilogue_ {nullptr};
- };
-
- // Base (B) should provide operator() that configures diag_record.
- //
- template <typename B>
- struct diag_prologue: B
- {
- diag_prologue (const diag_epilogue& e): B (), epilogue_ (e) {}
-
- template <typename... A>
- diag_prologue (const diag_epilogue& e, A&&... a)
- : B (forward<A> (a)...), epilogue_ (e) {}
-
- template <typename T>
- diag_record
- operator<< (const T& x) const
- {
- diag_record r;
- r.append (epilogue_);
- B::operator() (r);
- r << x;
- return r;
- }
-
- friend const diag_record&
- operator<< (const diag_record& r, const diag_prologue& p)
- {
- r.append (p.epilogue_);
- p (r);
- return r;
- }
-
- private:
- const diag_epilogue& epilogue_;
- };
-
- // Base (B) should provide operator() that returns diag_prologue.
- //
- template <typename B>
- struct diag_mark: B
- {
- diag_mark (): B () {}
-
- template <typename... A>
- diag_mark (A&&... a): B (forward<A> (a)...) {}
-
- template <typename T>
- diag_record
- operator<< (const T& x) const
- {
- return B::operator() () << x;
- }
-
- friend const diag_record&
- operator<< (const diag_record& r, const diag_mark& m)
- {
- return r << m ();
- }
- };
-
- // Prologues.
- //
- struct simple_prologue_base
- {
- explicit
- simple_prologue_base (severity s, const char* name)
- : sev_ (s), name_ (name) {}
-
- void
- operator() (const diag_record& r) const
- {
- diag_entry& e (r.current ());
- e.sev = sev_;
- e.name = name_;
- }
-
- private:
- severity sev_;
- const char* name_;
- };
- typedef diag_prologue<simple_prologue_base> simple_prologue;
-
- struct location_prologue_base
- {
- location_prologue_base (severity s,
- const char* name,
- const location& l)
- : sev_ (s), name_ (name), loc_ (l) {}
-
- void
- operator() (const diag_record& r) const
- {
- diag_entry& e (r.current ());
- e.sev = sev_;
- e.name = name_;
- e.loc = loc_; //@@ I think we can probably move it.
- }
-
- private:
- severity sev_;
- const char* name_;
- const location loc_;
- };
- typedef diag_prologue<location_prologue_base> location_prologue;
-
- // Marks.
- //
- struct basic_mark_base
- {
- explicit
- basic_mark_base (severity s,
- const diag_epilogue& e,
- const char* name = nullptr,
- const void* data = nullptr)
- : sev_ (s), epilogue_ (e), name_ (name), data_ (data) {}
-
- simple_prologue
- operator() () const
- {
- return simple_prologue (epilogue_, sev_, name_);
- }
-
- location_prologue
- operator() (const location& l) const
- {
- return location_prologue (epilogue_, sev_, name_, l);
- }
-
- template <typename L>
- location_prologue
- operator() (const L& l) const
- {
- // get_location() is the user-supplied ADL-searched function.
- //
- return location_prologue (
- epilogue_, sev_, name_, get_location (l, data_));
- }
-
- private:
- severity sev_;
- const diag_epilogue& epilogue_;
- const char* name_;
- const void* data_;
- };
- typedef diag_mark<basic_mark_base> basic_mark;
-
- template <typename E>
- struct fail_mark_base
- {
- explicit
- fail_mark_base (const char* name = nullptr, const void* data = nullptr)
- : name_ (name), data_ (data) {}
-
- simple_prologue
- operator() () const
- {
- return simple_prologue (epilogue_, severity::error, name_);
- }
-
- location_prologue
- operator() (const location& l) const
- {
- return location_prologue (epilogue_, severity::error, name_, l);
- }
-
- template <typename L>
- location_prologue
- operator() (const L& l) const
- {
- return location_prologue (
- epilogue_, severity::error, name_, get_location (l, data_));
- }
-
- static void
- epilogue (diag_data&& d) {throw E (move (d));}
-
- private:
- const diag_epilogue epilogue_ {&epilogue};
- const char* name_;
- const void* data_;
- };
-
- template <typename E>
- using fail_mark = diag_mark<fail_mark_base<E>>;
-}
-
-#endif // BREP_DIAGNOSTICS
diff --git a/brep/diagnostics.cxx b/brep/diagnostics.cxx
deleted file mode 100644
index b0d122f..0000000
--- a/brep/diagnostics.cxx
+++ /dev/null
@@ -1,30 +0,0 @@
-// file : brep/diagnostics.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/diagnostics>
-
-using namespace std;
-
-namespace brep
-{
- diag_record::
- ~diag_record () noexcept(false)
- {
- // Don't flush the record if this destructor was called as part of
- // the stack unwinding. Right now this means we cannot use this
- // mechanism in destructors, which is not a big deal, except for
- // one place: exception_guard. So for now we are going to have
- // this ugly special check which we will be able to get rid of
- // once C++17 uncaught_exceptions() becomes available.
- //
- if (!data_.empty () &&
- (!uncaught_exception () /*|| exception_unwinding_dtor*/))
- {
- data_.back ().msg = os_.str (); // Save last message.
-
- assert (epilogue_ != nullptr);
- (*epilogue_) (move (data_)); // Can throw.
- }
- }
-}
diff --git a/brep/mod-package-details b/brep/mod-package-details
deleted file mode 100644
index 4dc6b18..0000000
--- a/brep/mod-package-details
+++ /dev/null
@@ -1,42 +0,0 @@
-// file : brep/mod-package-details -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_MOD_PACKAGE_DETAILS
-#define BREP_MOD_PACKAGE_DETAILS
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/options>
-#include <brep/database-module>
-
-namespace brep
-{
- class package_details: public database_module
- {
- public:
- package_details () = default;
-
- // Create a shallow copy (handling instance) if initialized and a deep
- // copy (context exemplar) otherwise.
- //
- explicit
- package_details (const package_details&);
-
- virtual bool
- handle (request&, response&);
-
- virtual const cli::options&
- cli_options () const {return options::package_details::description ();}
-
- private:
- virtual void
- init (cli::scanner&);
-
- private:
- shared_ptr<options::package_details> options_;
- };
-}
-
-#endif // BREP_MOD_PACKAGE_DETAILS
diff --git a/brep/mod-package-details.cxx b/brep/mod-package-details.cxx
deleted file mode 100644
index 10bd72c..0000000
--- a/brep/mod-package-details.cxx
+++ /dev/null
@@ -1,257 +0,0 @@
-// file : brep/mod-package-details.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/mod-package-details>
-
-#include <xml/serializer>
-
-#include <odb/session.hxx>
-#include <odb/database.hxx>
-#include <odb/transaction.hxx>
-
-#include <web/xhtml>
-#include <web/module>
-#include <web/xhtml-fragment>
-#include <web/mime-url-encoding>
-
-#include <brep/page>
-#include <brep/options>
-#include <brep/package>
-#include <brep/package-odb>
-
-using namespace odb::core;
-using namespace brep::cli;
-
-// While currently the user-defined copy constructor is not required (we don't
-// need to deep copy nullptr's), it is a good idea to keep the placeholder
-// ready for less trivial cases.
-//
-brep::package_details::
-package_details (const package_details& r)
- : database_module (r),
- options_ (r.initialized_ ? r.options_ : nullptr)
-{
-}
-
-void brep::package_details::
-init (scanner& s)
-{
- MODULE_DIAG;
-
- options_ = make_shared<options::package_details> (
- s, unknown_mode::fail, unknown_mode::fail);
-
- database_module::init (*options_);
-
- if (options_->root ().empty ())
- options_->root (dir_path ("/"));
-}
-
-template <typename T>
-static inline query<T>
-search_params (const brep::string& n, const brep::string& q)
-{
- using query = query<T>;
-
- return "(" +
- (q.empty ()
- ? query ("NULL")
- : "plainto_tsquery (" + query::_val (q) + ")") +
- "," +
- query::_val (n) +
- ")";
-}
-
-bool brep::package_details::
-handle (request& rq, response& rs)
-{
- using namespace web;
- using namespace web::xhtml;
-
- MODULE_DIAG;
-
- const size_t res_page (options_->search_results ());
- const dir_path& root (options_->root ());
-
- const string& name (*rq.path ().rbegin ());
- const string ename (mime_url_encode (name));
-
- params::package_details params;
- bool full;
-
- try
- {
- name_value_scanner s (rq.parameters ());
- params = params::package_details (
- s, unknown_mode::fail, unknown_mode::fail);
-
- full = params.form () == page_form::full;
- }
- catch (const cli::exception& e)
- {
- throw invalid_request (400, e.what ());
- }
-
- size_t page (params.page ());
- const string& squery (params.query ());
-
- auto url (
- [&ename](bool f = false,
- const string& q = "",
- size_t p = 0,
- const string& a = "") -> string
- {
- string s ("?");
- string u (ename);
-
- if (f) { u += "?f=full"; s = "&"; }
- if (!q.empty ()) { u += s + "q=" + mime_url_encode (q); s = "&"; }
- if (p > 0) { u += s + "p=" + to_string (p); s = "&"; }
- if (!a.empty ()) { u += '#' + a; }
- return u;
- });
-
- xml::serializer s (rs.content (), name);
-
- s << HTML
- << HEAD
- << TITLE
- << name;
-
- if (!squery.empty ())
- s << " " << squery;
-
- s << ~TITLE
- << CSS_LINKS (path ("package-details.css"), root)
- //
- // This hack is required to avoid the "flash of unstyled content", which
- // happens due to the presence of the autofocus attribute in the input
- // element of the search form. The problem appears in Firefox and has a
- // (4-year old, at the time of this writing) bug report:
- //
- // https://bugzilla.mozilla.org/show_bug.cgi?id=712130.
- //
- << SCRIPT << " " << ~SCRIPT
- << ~HEAD
- << BODY
- << DIV_HEADER (root, options_->logo (), options_->menu ())
- << DIV(ID="content");
-
- if (full)
- s << CLASS("full");
-
- s << DIV(ID="heading")
- << H1 << A(HREF=url ()) << name << ~A << ~H1
- << A(HREF=url (!full, squery, page))
- << (full ? "[brief]" : "[full]")
- << ~A
- << ~DIV;
-
- session sn;
- transaction t (db_->begin ());
-
- shared_ptr<package> pkg;
- {
- latest_package lp;
- if (!db_->query_one<latest_package> (
- query<latest_package>(
- "(" + query<latest_package>::_val (name) + ")"), lp))
- throw invalid_request (404, "Package '" + name + "' not found");
-
- pkg = db_->load<package> (lp.id);
- }
-
- const auto& licenses (pkg->license_alternatives);
-
- if (page == 0)
- {
- // Display package details on the first page only.
- //
- s << H2 << pkg->summary << ~H2;
-
- static const string id ("description");
- if (const auto& d = pkg->description)
- s << (full
- ? P_DESCRIPTION (*d, id)
- : P_DESCRIPTION (*d, options_->package_description (),
- url (!full, squery, page, id)));
-
- s << TABLE(CLASS="proplist", ID="package")
- << TBODY
- << TR_LICENSE (licenses)
- << TR_URL (pkg->url)
- << TR_EMAIL (pkg->email)
- << TR_TAGS (pkg->tags, root)
- << ~TBODY
- << ~TABLE;
- }
-
- auto pkg_count (
- db_->query_value<package_count> (
- search_params<package_count> (name, squery)));
-
- s << FORM_SEARCH (squery)
- << DIV_COUNTER (pkg_count, "Version", "Versions");
-
- // Enclose the subsequent tables to be able to use nth-child CSS selector.
- //
- s << DIV;
- for (const auto& pr:
- db_->query<package_search_rank> (
- search_params<package_search_rank> (name, squery) +
- "ORDER BY rank DESC, version_epoch DESC, "
- "version_canonical_upstream DESC, version_canonical_release DESC, "
- "version_revision DESC" +
- "OFFSET" + to_string (page * res_page) +
- "LIMIT" + to_string (res_page)))
- {
- shared_ptr<package> p (db_->load<package> (pr.id));
-
- s << TABLE(CLASS="proplist version")
- << TBODY
- << TR_VERSION (name, p->version.string (), root)
-
- // @@ Shouldn't we skip low priority row ? Don't think so, why?
- //
- << TR_PRIORITY (p->priority);
-
- // Comparing objects of the license_alternatives class as being of the
- // vector<vector<string>> class, so comments are not considered.
- //
- if (p->license_alternatives != licenses)
- s << TR_LICENSE (p->license_alternatives);
-
- assert (p->internal ());
-
- // @@ Shouldn't we make package location to be a link to the proper
- // place of the About page, describing corresponding repository?
- // Yes, I think that's sounds reasonable, once we have about.
- // Or maybe it can be something more valuable like a link to the
- // repository package search page ?
- //
- // @@ In most cases package location will be the same for all versions
- // of the same package. Shouldn't we put package location to the
- // package summary part and display it here only if it differs
- // from the one in the summary ?
- //
- // Hm, I am not so sure about this. Consider: stable/testing/unstable.
- //
- s << TR_LOCATION (p->internal_repository.object_id (), root)
- << TR_DEPENDS (p->dependencies, root)
- << TR_REQUIRES (p->requirements)
- << ~TBODY
- << ~TABLE;
- }
- s << ~DIV;
-
- t.commit ();
-
- s << DIV_PAGER (page, pkg_count, res_page, options_->search_pages (),
- url (full, squery))
- << ~DIV
- << ~BODY
- << ~HTML;
-
- return true;
-}
diff --git a/brep/mod-package-search b/brep/mod-package-search
deleted file mode 100644
index bb762cd..0000000
--- a/brep/mod-package-search
+++ /dev/null
@@ -1,42 +0,0 @@
-// file : brep/mod-package-search -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_MOD_PACKAGE_SEARCH
-#define BREP_MOD_PACKAGE_SEARCH
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/options>
-#include <brep/database-module>
-
-namespace brep
-{
- class package_search: public database_module
- {
- public:
- package_search () = default;
-
- // Create a shallow copy (handling instance) if initialized and a deep
- // copy (context exemplar) otherwise.
- //
- explicit
- package_search (const package_search&);
-
- virtual bool
- handle (request&, response&);
-
- virtual const cli::options&
- cli_options () const {return options::package_search::description ();}
-
- private:
- virtual void
- init (cli::scanner&);
-
- private:
- shared_ptr<options::package_search> options_;
- };
-}
-
-#endif // BREP_MOD_PACKAGE_SEARCH
diff --git a/brep/mod-package-search.cxx b/brep/mod-package-search.cxx
deleted file mode 100644
index 9769783..0000000
--- a/brep/mod-package-search.cxx
+++ /dev/null
@@ -1,181 +0,0 @@
-// file : brep/mod-package-search.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/mod-package-search>
-
-#include <xml/serializer>
-
-#include <odb/session.hxx>
-#include <odb/database.hxx>
-#include <odb/transaction.hxx>
-#include <odb/schema-catalog.hxx>
-
-#include <web/xhtml>
-#include <web/module>
-#include <web/xhtml-fragment>
-#include <web/mime-url-encoding>
-
-#include <brep/version>
-
-#include <brep/page>
-#include <brep/options>
-#include <brep/package>
-#include <brep/package-odb>
-
-using namespace odb::core;
-using namespace brep::cli;
-
-// While currently the user-defined copy constructor is not required (we don't
-// need to deep copy nullptr's), it is a good idea to keep the placeholder
-// ready for less trivial cases.
-//
-brep::package_search::
-package_search (const package_search& r)
- : database_module (r),
- options_ (r.initialized_ ? r.options_ : nullptr)
-{
-}
-
-void brep::package_search::
-init (scanner& s)
-{
- MODULE_DIAG;
-
- options_ = make_shared<options::package_search> (
- s, unknown_mode::fail, unknown_mode::fail);
-
- database_module::init (*options_);
-
- if (options_->root ().empty ())
- options_->root (dir_path ("/"));
-
- // Check that the database schema matches the current one. It's enough to
- // perform the check in just a single module implementation (and we don't
- // do in the dispatcher because it doesn't use the database).
- //
- // Note that the failure can be reported by each web server worker process.
- // While it could be tempting to move the check to the
- // repository_root::version() function, it would be wrong. The function can
- // be called by a different process (usually the web server root one) not
- // having the proper permissions to access the database.
- //
- if (schema_catalog::current_version (*db_) != db_->schema_version ())
- fail << "database schema differs from the current one (module "
- << BREP_VERSION_STR << ")";
-}
-
-template <typename T>
-static inline query<T>
-search_param (const brep::string& q)
-{
- using query = query<T>;
- return "(" +
- (q.empty ()
- ? query ("NULL")
- : "plainto_tsquery (" + query::_val (q) + ")") +
- ")";
-}
-
-bool brep::package_search::
-handle (request& rq, response& rs)
-{
- using namespace web::xhtml;
-
- MODULE_DIAG;
-
- const size_t res_page (options_->search_results ());
- const dir_path& root (options_->root ());
-
- params::package_search params;
-
- try
- {
- name_value_scanner s (rq.parameters ());
- params = params::package_search (
- s, unknown_mode::fail, unknown_mode::fail);
- }
- catch (const unknown_argument& e)
- {
- throw invalid_request (400, e.what ());
- }
-
- size_t page (params.page ());
- const string& squery (params.query ());
- string squery_param (squery.empty ()
- ? ""
- : "?q=" + web::mime_url_encode (squery));
-
-
- static const string title ("Packages");
- xml::serializer s (rs.content (), title);
-
- s << HTML
- << HEAD
- << TITLE
- << title;
-
- if (!squery.empty ())
- s << " " << squery;
-
- s << ~TITLE
- << CSS_LINKS (path ("package-search.css"), root)
- //
- // This hack is required to avoid the "flash of unstyled content", which
- // happens due to the presence of the autofocus attribute in the input
- // element of the search form. The problem appears in Firefox and has a
- // (4-year old, at the time of this writing) bug report:
- //
- // https://bugzilla.mozilla.org/show_bug.cgi?id=712130.
- //
- << SCRIPT << " " << ~SCRIPT
- << ~HEAD
- << BODY
- << DIV_HEADER (root, options_->logo (), options_->menu ())
- << DIV(ID="content");
-
- session sn;
- transaction t (db_->begin ());
-
- auto pkg_count (
- db_->query_value<latest_package_count> (
- search_param<latest_package_count> (squery)));
-
- s << FORM_SEARCH (squery)
- << DIV_COUNTER (pkg_count, "Package", "Packages");
-
- // Enclose the subsequent tables to be able to use nth-child CSS selector.
- //
- s << DIV;
- for (const auto& pr:
- db_->query<latest_package_search_rank> (
- search_param<latest_package_search_rank> (squery) +
- "ORDER BY rank DESC, name" +
- "OFFSET" + to_string (page * res_page) +
- "LIMIT" + to_string (res_page)))
- {
- shared_ptr<package> p (db_->load<package> (pr.id));
-
- s << TABLE(CLASS="proplist package")
- << TBODY
- << TR_NAME (p->id.name, squery_param, root)
- << TR_SUMMARY (p->summary)
- << TR_LICENSE (p->license_alternatives)
- << TR_TAGS (p->tags, root)
- << TR_DEPENDS (p->dependencies, root)
- << TR_REQUIRES (p->requirements)
- << ~TBODY
- << ~TABLE;
- }
- s << ~DIV;
-
- t.commit ();
-
- s << DIV_PAGER (page, pkg_count, res_page, options_->search_pages (),
- root.string () + squery_param)
- << ~DIV
- << ~BODY
- << ~HTML;
-
- return true;
-}
diff --git a/brep/mod-package-version-details b/brep/mod-package-version-details
deleted file mode 100644
index a463511..0000000
--- a/brep/mod-package-version-details
+++ /dev/null
@@ -1,45 +0,0 @@
-// file : brep/mod-package-version-details -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_MOD_PACKAGE_VERSION_DETAILS
-#define BREP_MOD_PACKAGE_VERSION_DETAILS
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/options>
-#include <brep/database-module>
-
-namespace brep
-{
- class package_version_details: public database_module
- {
- public:
- package_version_details () = default;
-
- // Create a shallow copy (handling instance) if initialized and a deep
- // copy (context exemplar) otherwise.
- //
- explicit
- package_version_details (const package_version_details&);
-
- virtual bool
- handle (request&, response&);
-
- virtual const cli::options&
- cli_options () const
- {
- return options::package_version_details::description ();
- }
-
- private:
- virtual void
- init (cli::scanner&);
-
- private:
- shared_ptr<options::package_version_details> options_;
- };
-}
-
-#endif // BREP_MOD_PACKAGE_VERSION_DETAILS
diff --git a/brep/mod-package-version-details.cxx b/brep/mod-package-version-details.cxx
deleted file mode 100644
index 21da41f..0000000
--- a/brep/mod-package-version-details.cxx
+++ /dev/null
@@ -1,319 +0,0 @@
-// file : brep/mod-package-version-details.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/mod-package-version-details>
-
-#include <xml/serializer>
-
-#include <odb/session.hxx>
-#include <odb/database.hxx>
-#include <odb/transaction.hxx>
-
-#include <web/xhtml>
-#include <web/module>
-#include <web/xhtml-fragment>
-#include <web/mime-url-encoding>
-
-#include <brep/page>
-#include <brep/options>
-#include <brep/package>
-#include <brep/package-odb>
-
-using namespace std;
-using namespace odb::core;
-using namespace brep::cli;
-
-// While currently the user-defined copy constructor is not required (we don't
-// need to deep copy nullptr's), it is a good idea to keep the placeholder
-// ready for less trivial cases.
-//
-brep::package_version_details::
-package_version_details (const package_version_details& r)
- : database_module (r),
- options_ (r.initialized_ ? r.options_ : nullptr)
-{
-}
-
-void brep::package_version_details::
-init (scanner& s)
-{
- MODULE_DIAG;
-
- options_ = make_shared<options::package_version_details> (
- s, unknown_mode::fail, unknown_mode::fail);
-
- database_module::init (*options_);
-
- if (options_->root ().empty ())
- options_->root (dir_path ("/"));
-}
-
-bool brep::package_version_details::
-handle (request& rq, response& rs)
-{
- using namespace web;
- using namespace web::xhtml;
- using brep::version; // Not to confuse with module::version.
-
- MODULE_DIAG;
-
- const dir_path& root (options_->root ());
-
- auto i (rq.path ().rbegin ());
- version ver;
-
- try
- {
- ver = version (*i++);
- }
- catch (const invalid_argument& )
- {
- throw invalid_request (400, "invalid package version format");
- }
-
- const string& sver (ver.string ());
-
- assert (i != rq.path ().rend ());
- const string& name (*i);
-
- params::package_version_details params;
- bool full;
-
- try
- {
- name_value_scanner s (rq.parameters ());
- params = params::package_version_details (
- s, unknown_mode::fail, unknown_mode::fail);
-
- full = params.form () == page_form::full;
- }
- catch (const unknown_argument& e)
- {
- throw invalid_request (400, e.what ());
- }
-
- auto url (
- [&sver](bool f = false, const string& a = "") -> string
- {
- string u (sver);
-
- if (f) { u += "?f=full"; }
- if (!a.empty ()) { u += '#' + a; }
- return u;
- });
-
- const string title (name + " " + sver);
- xml::serializer s (rs.content (), title);
-
- s << HTML
- << HEAD
- << TITLE << title << ~TITLE
- << CSS_LINKS (path ("package-version-details.css"), root)
- << ~HEAD
- << BODY
- << DIV_HEADER (root, options_->logo (), options_->menu ())
- << DIV(ID="content");
-
- if (full)
- s << CLASS("full");
-
- s << DIV(ID="heading")
- << H1
- << A(HREF=root / path (mime_url_encode (name))) << name << ~A
- << "/"
- << A(HREF=url ()) << sver << ~A
- << ~H1
- << A(HREF=url (!full)) << (full ? "[brief]" : "[full]") << ~A
- << ~DIV;
-
- bool not_found (false);
- shared_ptr<package> pkg;
-
- session sn;
- transaction t (db_->begin ());
-
- try
- {
- pkg = db_->load<package> (package_id (name, ver));
-
- // If the requested package turned up to be an "external" one just
- // respond that no "internal" package is present.
- //
- not_found = !pkg->internal ();
- }
- catch (const object_not_persistent& )
- {
- not_found = true;
- }
-
- if (not_found)
- throw invalid_request (404, "Package '" + title + "' not found");
-
- s << H2 << pkg->summary << ~H2;
-
- static const string id ("description");
- if (const auto& d = pkg->description)
- s << (full
- ? P_DESCRIPTION (*d, id)
- : P_DESCRIPTION (*d, options_->package_description (),
- url (!full, id)));
-
- assert (pkg->location && pkg->sha256sum);
-
- s << TABLE(CLASS="proplist", ID="version")
- << TBODY
-
- // Repeat version here since it can be cut out in the header.
- //
- << TR_VERSION (pkg->version.string ())
-
- << TR_PRIORITY (pkg->priority)
- << TR_LICENSES (pkg->license_alternatives)
- << TR_LOCATION (pkg->internal_repository.object_id (), root)
- << TR_DOWNLOAD (pkg->internal_repository.load ()->location.string () +
- "/" + pkg->location->string ())
- << TR_SHA256SUM (*pkg->sha256sum)
- << ~TBODY
- << ~TABLE
-
- << TABLE(CLASS="proplist", ID="package")
- << TBODY
- << TR_URL (pkg->url)
- << TR_EMAIL (pkg->email);
-
- const auto& pu (pkg->package_url);
- if (pu && *pu != pkg->url)
- s << TR_URL (*pu, "pkg-url");
-
- const auto& pe (pkg->package_email);
- if (pe && *pe != pkg->email)
- s << TR_EMAIL (*pe, "pkg-email");
-
- s << TR_TAGS (pkg->tags, root)
- << ~TBODY
- << ~TABLE;
-
- const auto& ds (pkg->dependencies);
- if (!ds.empty ())
- {
- s << H3 << "Depends" << ~H3
- << TABLE(CLASS="proplist", ID="depends")
- << TBODY;
-
- for (const auto& da: ds)
- {
- s << TR(CLASS="depends")
- << TH;
-
- if (da.conditional)
- s << "?";
-
- s << ~TH
- << TD
- << SPAN(CLASS="value");
-
- for (const auto& d: da)
- {
- if (&d != &da[0])
- s << " | ";
-
- shared_ptr<package> p (d.package.load ());
- assert (p->internal () || !p->other_repositories.empty ());
-
- shared_ptr<repository> r (
- p->internal ()
- ? p->internal_repository.load ()
- : p->other_repositories[0].load ());
-
- const auto& dcon (d.constraint);
- const string& dname (p->id.name);
- string ename (mime_url_encode (dname));
-
- if (r->url)
- {
- string u (*r->url + ename);
- s << A(HREF=u) << dname << ~A;
-
- if (dcon)
- s << ' ' << A(HREF=u + "/" + p->version.string ()) << *dcon << ~A;
- }
- else if (p->internal ())
- {
- path u (root / path (ename));
- s << A(HREF=u) << dname << ~A;
-
- if (dcon)
- s << ' ' << A(HREF=u / path (p->version.string ())) << *dcon << ~A;
- }
- else
- // Display the dependency as a plain text if no repository URL
- // available.
- //
- s << d;
- }
-
- s << ~SPAN
- << SPAN_COMMENT (da.comment)
- << ~TD
- << ~TR;
- }
-
- s << ~TBODY
- << ~TABLE;
- }
-
- t.commit ();
-
- const auto& rm (pkg->requirements);
- if (!rm.empty ())
- {
- s << H3 << "Requires" << ~H3
- << TABLE(CLASS="proplist", ID="requires")
- << TBODY;
-
- for (const auto& ra: rm)
- {
- s << TR(CLASS="requires")
- << TH;
-
- if (ra.conditional)
- s << "?";
-
- s << ~TH
- << TD
- << SPAN(CLASS="value");
-
- for (const auto& r: ra)
- {
- if (&r != &ra[0])
- s << " | ";
-
- s << r;
- }
-
- s << ~SPAN
- << SPAN_COMMENT (ra.comment)
- << ~TD
- << ~TR;
- }
-
- s << ~TBODY
- << ~TABLE;
- }
-
- const auto& ch (pkg->changes);
- if (!ch.empty ())
- s << H3 << "Changes" << ~H3
- << (full
- ? PRE_CHANGES (ch)
- : PRE_CHANGES (ch,
- options_->package_changes (),
- url (!full, "changes")));
-
- s << ~DIV
- << ~BODY
- << ~HTML;
-
- return true;
-}
diff --git a/brep/mod-repository-details b/brep/mod-repository-details
deleted file mode 100644
index 49ad629..0000000
--- a/brep/mod-repository-details
+++ /dev/null
@@ -1,42 +0,0 @@
-// file : brep/mod-repository-details -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_MOD_REPOSITORY_DETAILS
-#define BREP_MOD_REPOSITORY_DETAILS
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/options>
-#include <brep/database-module>
-
-namespace brep
-{
- class repository_details: public database_module
- {
- public:
- repository_details () = default;
-
- // Create a shallow copy (handling instance) if initialized and a deep
- // copy (context exemplar) otherwise.
- //
- explicit
- repository_details (const repository_details&);
-
- virtual bool
- handle (request&, response&);
-
- virtual const cli::options&
- cli_options () const {return options::repository_details::description ();}
-
- private:
- virtual void
- init (cli::scanner&);
-
- private:
- shared_ptr<options::repository_details> options_;
- };
-}
-
-#endif // BREP_MOD_REPOSITORY_DETAILS
diff --git a/brep/mod-repository-details.cxx b/brep/mod-repository-details.cxx
deleted file mode 100644
index b0e2b95..0000000
--- a/brep/mod-repository-details.cxx
+++ /dev/null
@@ -1,146 +0,0 @@
-// file : brep/mod-repository-details.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/mod-repository-details>
-
-#include <time.h> // tzset()
-
-#include <sstream>
-#include <algorithm> // max()
-
-#include <xml/serializer>
-
-#include <odb/database.hxx>
-#include <odb/transaction.hxx>
-
-#include <butl/timestamp>
-
-#include <web/xhtml>
-#include <web/module>
-#include <web/xhtml-fragment>
-#include <web/mime-url-encoding>
-
-#include <brep/page>
-#include <brep/options>
-#include <brep/package>
-#include <brep/package-odb>
-
-using namespace std;
-using namespace odb::core;
-using namespace brep::cli;
-
-// While currently the user-defined copy constructor is not required (we don't
-// need to deep copy nullptr's), it is a good idea to keep the placeholder
-// ready for less trivial cases.
-//
-brep::repository_details::
-repository_details (const repository_details& r)
- : database_module (r),
- options_ (r.initialized_ ? r.options_ : nullptr)
-{
-}
-
-void brep::repository_details::
-init (scanner& s)
-{
- MODULE_DIAG;
-
- options_ = make_shared<options::repository_details> (
- s, unknown_mode::fail, unknown_mode::fail);
-
- database_module::init (*options_);
-
- if (options_->root ().empty ())
- options_->root (dir_path ("/"));
-
- tzset (); // To use butl::to_stream() later on.
-}
-
-bool brep::repository_details::
-handle (request& rq, response& rs)
-{
- using namespace web::xhtml;
-
- MODULE_DIAG;
-
- const dir_path& root (options_->root ());
-
- // Make sure no parameters passed.
- //
- try
- {
- name_value_scanner s (rq.parameters ());
- params::repository_details (s, unknown_mode::fail, unknown_mode::fail);
- }
- catch (const unknown_argument& e)
- {
- throw invalid_request (400, e.what ());
- }
-
- static const string title ("About");
- xml::serializer s (rs.content (), title);
-
- s << HTML
- << HEAD
- << TITLE << title << ~TITLE
- << CSS_LINKS (path ("repository-details.css"), root)
- << ~HEAD
- << BODY
- << DIV_HEADER (root, options_->logo (), options_->menu ())
- << DIV(ID="content");
-
- transaction t (db_->begin ());
-
- using query = query<repository>;
-
- for (const auto& r:
- db_->query<repository> (
- query::internal + "ORDER BY" + query::priority))
- {
- //@@ Feels like a lot of trouble (e.g., id_attribute()) for very
- // dubious value. A link to the package search page just for
- // this repository would probably be more useful.
- //
- string id (html_id (r.name));
- s << H1(ID=id)
- << A(HREF="#" + web::mime_url_encode (id)) << r.display_name << ~A
- << ~H1;
-
- if (r.summary)
- s << H2 << *r.summary << ~H2;
-
- if (r.description)
- s << P_DESCRIPTION (*r.description);
-
- if (r.email)
- {
- const email& e (*r.email);
-
- s << P
- << A(HREF="mailto:" + e) << e << ~A;
-
- if (!e.comment.empty ())
- s << " (" << e.comment << ")";
-
- s << ~P;
- }
-
- ostringstream o;
- butl::to_stream (o,
- max (r.packages_timestamp, r.repositories_timestamp),
- "%Y-%m-%d %H:%M:%S%[.N] %Z",
- true,
- true);
-
- s << P << o.str () << ~P;
- }
-
- t.commit ();
-
- s << ~DIV
- << ~BODY
- << ~HTML;
-
- return true;
-}
diff --git a/brep/mod-repository-root b/brep/mod-repository-root
deleted file mode 100644
index f2c2ba0..0000000
--- a/brep/mod-repository-root
+++ /dev/null
@@ -1,60 +0,0 @@
-// file : brep/mod-repository-root -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_MOD_REPOSITORY_ROOT
-#define BREP_MOD_REPOSITORY_ROOT
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/module>
-#include <brep/options>
-
-namespace brep
-{
- class package_search;
- class package_details;
- class package_version_details;
- class repository_details;
-
- class repository_root: public module
- {
- public:
- repository_root ();
-
- // Create a shallow copy (handling instance) if initialized and a deep
- // copy (context exemplar) otherwise.
- //
- explicit
- repository_root (const repository_root&);
-
- private:
- virtual bool
- handle (request&, response&);
-
- virtual const cli::options&
- cli_options () const {return options::repository_root::description ();}
-
- virtual option_descriptions
- options ();
-
- virtual void
- init (const name_values&);
-
- virtual void
- init (cli::scanner&);
-
- virtual void
- version ();
-
- private:
- shared_ptr<package_search> package_search_;
- shared_ptr<package_details> package_details_;
- shared_ptr<package_version_details> package_version_details_;
- shared_ptr<repository_details> repository_details_;
- shared_ptr<options::repository_root> options_;
- };
-}
-
-#endif // BREP_MOD_REPOSITORY_ROOT
diff --git a/brep/mod-repository-root.cxx b/brep/mod-repository-root.cxx
deleted file mode 100644
index 7d0adc9..0000000
--- a/brep/mod-repository-root.cxx
+++ /dev/null
@@ -1,263 +0,0 @@
-// file : brep/mod-repository-root.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/mod-repository-root>
-
-#include <sstream>
-
-#include <web/module>
-
-#include <brep/version>
-
-#include <brep/module>
-#include <brep/options>
-#include <brep/mod-package-search>
-#include <brep/mod-package-details>
-#include <brep/mod-repository-details>
-#include <brep/mod-package-version-details>
-
-using namespace std;
-using namespace brep::cli;
-
-namespace brep
-{
- // request_proxy
- //
- class request_proxy: public request
- {
- public:
- request_proxy (request& r, const name_values& p)
- : request_ (r), parameters_ (p) {}
-
- virtual const path_type&
- path () {return request_.path ();}
-
- virtual const name_values&
- parameters () {return parameters_;}
-
- virtual const name_values&
- cookies () {return request_.cookies ();}
-
- virtual istream&
- content (bool buffer) {return request_.content (buffer);}
-
- private:
- request& request_;
- const name_values& parameters_;
- };
-
- // repository_root
- //
- repository_root::
- repository_root ()
- : package_search_ (make_shared<package_search> ()),
- package_details_ (make_shared<package_details> ()),
- package_version_details_ (make_shared<package_version_details> ()),
- repository_details_ (make_shared<repository_details> ())
- {
- }
-
- repository_root::
- repository_root (const repository_root& r)
- : module (r),
- //
- // Deep/shallow-copy sub-modules depending on whether this is an
- // exemplar/handler.
- //
- package_search_ (
- r.initialized_
- ? r.package_search_
- : make_shared<package_search> (*r.package_search_)),
- package_details_ (
- r.initialized_
- ? r.package_details_
- : make_shared<package_details> (*r.package_details_)),
- package_version_details_ (
- r.initialized_
- ? r.package_version_details_
- : make_shared<package_version_details> (
- *r.package_version_details_)),
- repository_details_ (
- r.initialized_
- ? r.repository_details_
- : make_shared<repository_details> (*r.repository_details_)),
- options_ (
- r.initialized_
- ? r.options_
- : nullptr)
- {
- }
-
- // Return amalgamation of repository_root and all its sub-modules option
- // descriptions.
- //
- option_descriptions repository_root::
- options ()
- {
- option_descriptions r (module::options ());
- append (r, package_search_->options ());
- append (r, package_details_->options ());
- append (r, package_version_details_->options ());
- append (r, repository_details_->options ());
- return r;
- }
-
- // Initialize sub-modules and parse own configuration options.
- //
- void repository_root::
- init (const name_values& v)
- {
- auto sub_init ([this, &v](module& m)
- {
- m.init (filter (v, m.options ()), *log_);
- });
-
- // Initialize sub-modules.
- //
- sub_init (*package_search_);
- sub_init (*package_details_);
- sub_init (*package_version_details_);
- sub_init (*repository_details_);
-
- // Parse own configuration options.
- //
- module::init (
- filter (v, convert (options::repository_root::description ())));
- }
-
- void repository_root::
- init (scanner& s)
- {
- MODULE_DIAG;
-
- options_ = make_shared<options::repository_root> (
- s, unknown_mode::fail, unknown_mode::fail);
-
- if (options_->root ().empty ())
- options_->root (dir_path ("/"));
- }
-
- bool repository_root::
- handle (request& rq, response& rs)
- {
- MODULE_DIAG;
-
- const dir_path& root (options_->root ());
-
- const path& rpath (rq.path ());
- if (!rpath.sub (root))
- return false;
-
- const path& lpath (rpath.leaf (root));
-
- // Delegate the request handling to the sub-module. Intercept exception
- // handling to add sub-module attribution.
- //
- auto handle = [&rs, this](module& m, request& rq, const char* name) -> bool
- {
- try
- {
- return m.handle (rq, rs, *log_);
- }
- catch (const invalid_request&)
- {
- // Preserve invalid_request exception type, so the web server can
- // properly respond to the client with a 4XX error code.
- //
- throw;
- }
- catch (const std::exception& e)
- {
- // All exception types inherited from std::exception (and different
- // from invalid_request) are handled by the web server as
- // std::exception. The only sensible way to handle them is to respond
- // to the client with the internal server error (500) code. By that
- // reason it is valid to reduce all these types to a single one.
- // Note that the server_error exception is handled internally by the
- // module::handle() function call.
- //
- throw runtime_error (string (name) + ": " + e.what ());
- }
- };
-
- if (lpath.empty ())
- {
- // Dispatch request handling to the repository_details or the
- // package_search module depending on the function name passed as a
- // first HTTP request parameter. The parameter should have no value
- // specified. Example: cppget.org/?about
- //
- const name_values& params (rq.parameters ());
- if (!params.empty () && !params.front ().value)
- {
- if (params.front ().name == "about")
- {
- // Cleanup not to confuse the selected module with the unknown
- // parameter.
- //
- name_values p (params);
- p.erase (p.begin ());
-
- request_proxy rp (rq, p);
- repository_details m (*repository_details_);
- return handle (m, rp, "repository_details");
- }
-
- throw invalid_request (400, "unknown function");
- }
- else
- {
- package_search m (*package_search_);
- return handle (m, rq, "package_search");
- }
- }
- else
- {
- // Dispatch request handling to the package_details or the
- // package_version_details module depending on the HTTP request URL path.
- //
- auto i (lpath.begin ());
- assert (i != lpath.end ());
-
- const string& n (*i++); // Package name.
-
- // Check if this is a package name and not a brep static content files
- // (CSS) directory name, a repository directory name, or a special file
- // name (the one starting with '.').
- //
- // @@ Shouldn't we validate that the package name is not "@", is not
- // digit-only, does not start with '.' while parsing and serializing
- // the package manifest ? Probably also need to mention these
- // contraints in the manifest.txt file.
- //
- if (n != "@" && n.find_first_not_of ("0123456789") != string::npos &&
- n[0] != '.')
- {
- if (i == lpath.end ())
- {
- package_details m (*package_details_);
- return handle (m, rq, "package_details");
- }
- else if (++i == lpath.end ())
- {
- package_version_details m (*package_version_details_);
- return handle (m, rq, "package_version_details");
- }
- }
- }
-
- return false;
- }
-
- void repository_root::
- version ()
- {
- MODULE_DIAG;
-
- info << "module " << BREP_VERSION_STR
- << ", libbrep " << LIBBREP_VERSION_STR
- << ", libbpkg " << LIBBPKG_VERSION_STR
- << ", libbutl " << LIBBUTL_VERSION_STR;
- }
-}
diff --git a/brep/module b/brep/module
deleted file mode 100644
index 7e5763a..0000000
--- a/brep/module
+++ /dev/null
@@ -1,201 +0,0 @@
-// file : brep/module -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_MODULE
-#define BREP_MODULE
-
-#include <web/module>
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/options>
-#include <brep/diagnostics>
-
-namespace brep
-{
- // Bring in commonly used names from the web namespace.
- //
- // @@ Maybe doing using namespace is the right way to handle this.
- // There will, however, most likely be a conflict between
- // web::module and our module. Or maybe not, need to try.
- //
- using web::status_code;
- using web::invalid_request;
- using web::sequence_error;
- using web::option_descriptions;
- using web::name_value;
- using web::name_values;
- using web::request;
- using web::response;
- using web::log;
-
- // This exception indicated a server error (5XX). In particular,
- // it is thrown by the fail diagnostics stream and is caught by the
- // module implementation where it is both logged as an error and
- // returned to the user with the 5XX status code.
- //
- struct server_error
- {
- diag_data data;
-
- server_error (diag_data&& d): data (move (d)) {}
- };
-
- // Every module member function that needs to produce any diagnostics
- // shall begin with:
- //
- // MODULE_DIAG;
- //
- // This will instantiate the fail, error, warn, info, and trace
- // diagnostics streams with the function's name.
- //
-#define MODULE_DIAG \
- const fail_mark<server_error> fail (__PRETTY_FUNCTION__); \
- const basic_mark error (severity::error, \
- this->log_writer_, \
- __PRETTY_FUNCTION__); \
- const basic_mark warn (severity::warning, \
- this->log_writer_, \
- __PRETTY_FUNCTION__); \
- const basic_mark info (severity::info, \
- this->log_writer_, \
- __PRETTY_FUNCTION__); \
- const basic_mark trace (severity::trace, \
- this->log_writer_, \
- __PRETTY_FUNCTION__)
-
- // Adaptation of the web::module to our needs.
- //
- class module: public web::module
- {
- // Diagnostics.
- //
- protected:
- // Trace verbosity level.
- //
- // 0 - tracing disabled.
- // 1 - brief information regarding irregular situations, which not being
- // an error can be of some interest.
- // 2 - @@ TODO: document
- //
- // While uint8 is more than enough, use uint16 for the ease of printing.
- //
- uint16_t verb_ = 0;
-
- template <class F> void l1 (const F& f) const {if (verb_ >= 1) f ();}
- template <class F> void l2 (const F& f) const {if (verb_ >= 2) f ();}
-
- // Set to true when the module is successfully initialized.
- //
- bool initialized_ {false};
-
- // Implementation details.
- //
- protected:
- module ();
- module (const module& );
-
- static name_values
- filter (const name_values&, const option_descriptions&);
-
- static option_descriptions
- convert (const cli::options&);
-
- static void
- append (option_descriptions& dst, const cli::options& src);
-
- static void
- append (option_descriptions& dst, const option_descriptions& src);
-
- // Can be used by module implementation to parse HTTP request parameters.
- //
- class name_value_scanner: public cli::scanner
- {
- public:
- name_value_scanner (const name_values&) noexcept;
-
- virtual bool
- more ();
-
- virtual const char*
- peek ();
-
- virtual const char*
- next ();
-
- virtual void
- skip ();
-
- private:
- const name_values& name_values_;
- name_values::const_iterator i_;
- bool name_;
- };
-
- public:
- virtual const cli::options&
- cli_options () const = 0;
-
- virtual void
- init (cli::scanner&) = 0;
-
- // Can be overriden by custom request dispatcher to initialize
- // sub-modules.
- //
- virtual void
- init (const name_values&);
-
- virtual void
- init (const name_values&, log&);
-
- virtual bool
- handle (request&, response&) = 0;
-
- virtual bool
- handle (request&, response&, log&);
-
- // web::module interface.
- //
- public:
- // Custom request dispatcher can aggregate its own option descriptions
- // with sub-modules option descriptions. In this case it should still call
- // the base implementation in order to include the brep::module's options.
- //
- virtual option_descriptions
- options ();
-
- private:
- virtual void
- version (log&);
-
- // Can be overriden by the module implementation to log version, etc.
- //
- virtual void
- version () {}
-
- name_values
- expand_options (const name_values&);
-
- // Diagnostics implementation details.
- //
- protected:
- log* log_ {nullptr}; // Diagnostics backend provided by the web server.
-
- private:
- // Extract function name from a __PRETTY_FUNCTION__.
- // Throw invalid_argument if fail to parse.
- //
- static string
- func_name (const char* pretty_name);
-
- void
- log_write (const diag_data&) const;
-
- protected:
- const diag_epilogue log_writer_;
- };
-}
-
-#endif // BREP_MODULE
diff --git a/brep/module.cxx b/brep/module.cxx
deleted file mode 100644
index 68969eb..0000000
--- a/brep/module.cxx
+++ /dev/null
@@ -1,410 +0,0 @@
-// file : brep/module.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/module>
-
-#include <httpd.h>
-#include <http_log.h>
-
-#include <sstream>
-#include <cstring> // strchr()
-#include <functional> // bind()
-
-#include <web/module>
-#include <web/apache/log>
-
-#include <brep/options>
-
-using namespace std;
-using namespace placeholders; // For std::bind's _1, etc.
-
-namespace brep
-{
- // module
- //
- bool module::
- handle (request& rq, response& rs, log& l)
- {
- log_ = &l;
-
- try
- {
- // Web server should terminate if initialization failed.
- //
- assert (initialized_);
-
- return handle (rq, rs);
- }
- catch (const server_error& e)
- {
- log_write (e.data);
-
- try
- {
- static const char* sev_str[] = {"error", "warning", "info", "trace"};
- ostream& o (rs.content (500, "text/plain;charset=utf-8"));
-
- for (const auto& d: e.data)
- {
- string name;
-
- try
- {
- name = func_name (d.name);
- }
- catch (const invalid_argument&)
- {
- // Log "pretty" function description, see in log file & fix.
- name = d.name;
- }
-
- o << name << ": " << sev_str[static_cast<size_t> (d.sev)] << ": "
- << d.msg << endl;
- }
- }
- catch (const sequence_error&)
- {
- // We tried to return the error status/description but some
- // content has already been written. Nothing we can do about
- // it.
- }
- }
-
- return true;
- }
-
- option_descriptions module::
- convert (const cli::options& o)
- {
- option_descriptions r;
- append (r, o);
- return r;
- }
-
- void module::
- append (option_descriptions& dst, const cli::options& src)
- {
- for (const auto& o: src)
- {
- bool v (!o.flag ());
- auto i (dst.emplace (o.name (), v));
- assert (i.first->second == v); // Consistent option/flag.
-
- for (const auto& a: o.aliases ())
- {
- i = dst.emplace (a, v);
- assert (i.first->second == v);
- }
- }
- }
-
- void module::
- append (option_descriptions& dst, const option_descriptions& src)
- {
- for (const auto& o: src)
- {
- auto i (dst.emplace (o));
- assert (i.first->second == o.second); // Consistent option/flag.
- }
- }
-
- name_values module::
- filter (const name_values& v, const option_descriptions& d)
- {
- name_values r;
- for (const auto& nv: v)
- {
- if (d.find (nv.name) != d.end ())
- r.push_back (nv);
- }
-
- return r;
- }
-
- // Convert CLI option descriptions to the general interface of option
- // descriptions, extend with brep::module own option descriptions.
- //
- option_descriptions module::
- options ()
- {
- option_descriptions r ({{"conf", true}});
- append (r, options::module::description ());
- append (r, cli_options ());
- return r;
- }
-
- // Expand option list parsing configuration files.
- //
- name_values module::
- expand_options (const name_values& v)
- {
- using namespace cli;
-
- vector<const char*> argv;
- for (const auto& nv: v)
- {
- argv.push_back (nv.name.c_str ());
-
- if (nv.value)
- argv.push_back (nv.value->c_str ());
- }
-
- int argc (argv.size ());
- argv_file_scanner s (0, argc, const_cast<char**> (argv.data ()), "conf");
-
- name_values r;
- const option_descriptions& o (options ());
-
- while (s.more ())
- {
- string n (s.next ());
- auto i (o.find (n));
-
- if (i == o.end ())
- throw unknown_argument (n);
-
- optional<string> v;
- if (i->second)
- v = s.next ();
-
- r.emplace_back (move (n), move (v));
- }
-
- return r;
- }
-
- // Parse options with a cli-generated scanner. Options verb and conf are
- // recognized by brep::module::init while others to be interpreted by the
- // derived init(). If there is an option which can not be interpreted
- // neither by brep::module nor by the derived class, then the web server
- // is terminated with a corresponding error message being logged. Though
- // this should not happen if the options() function returned the correct
- // set of options.
- //
- void module::
- init (const name_values& options, log& log)
- {
- assert (!initialized_);
-
- log_ = &log;
-
- try
- {
- name_values opts (expand_options (options));
-
- // Read module implementation configuration.
- //
- init (opts);
-
- // Read brep::module configuration.
- //
- static option_descriptions od (
- convert (options::module::description ()));
-
- name_values mo (filter (opts, od));
- name_value_scanner s (mo);
- options::module o (s, cli::unknown_mode::fail, cli::unknown_mode::fail);
-
- verb_ = o.verbosity ();
- initialized_ = true;
- }
- catch (const server_error& e)
- {
- log_write (e.data);
- throw runtime_error ("initialization failed");
- }
- catch (const cli::exception& e)
- {
- ostringstream o;
- e.print (o);
- throw runtime_error (o.str ());
- }
- }
-
- void module::
- init (const name_values& options)
- {
- name_value_scanner s (options);
- init (s);
- assert (!s.more ()); // Module didn't handle its options.
- }
-
- module::
- module (): log_writer_ (bind (&module::log_write, this, _1)) {}
-
- // Custom copy constructor is required to initialize log_writer_ properly.
- //
- module::
- module (const module& m): module ()
- {
- verb_ = m.verb_;
- initialized_ = m.initialized_;
- }
-
-// For function func declared like this:
-// using B = std::string (*)(int);
-// using A = B (*)(int,int);
-// A func(B (*)(char),B (*)(wchar_t));
-// __PRETTY_FUNCTION__ looks like this:
-// virtual std::string (* (* brep::search::func(std::string (* (*)(char))(int)
-// ,std::string (* (*)(wchar_t))(int)) const)(int, int))(int)
-//
- string module::
- func_name (const char* pretty_name)
- {
- const char* e (strchr (pretty_name, ')'));
-
- if (e && e > pretty_name)
- {
- // Position e at last matching '(' which is the beginning of the
- // argument list..
- //
- size_t d (1);
-
- do
- {
- switch (*--e)
- {
- case ')': ++d; break;
- case '(': --d; break;
- }
- }
- while (d && e > pretty_name);
-
- if (!d && e > pretty_name)
- {
- // Position e at the character following the function name.
- //
- while (e > pretty_name &&
- (*e != '(' || *(e - 1) == ' ' || *(e - 1) == ')'))
- --e;
-
- if (e > pretty_name)
- {
- // Position b at the beginning of the qualified function name.
- //
- const char* b (e);
- while (--b > pretty_name && *b != ' ');
- if (*b == ' ') ++b;
-
- return string (b, e - b);
- }
- }
- }
-
- throw invalid_argument ("::brep::module::func_name");
- }
-
- void module::
- log_write (const diag_data& d) const
- {
- if (log_ == nullptr)
- return; // No backend yet.
-
- //@@ Cast log_ to apache::log and write the records.
- //
- auto al (dynamic_cast<web::apache::log*> (log_));
-
- if (al)
- {
- // Considered using lambda for mapping but looks too verbose while can
- // be a bit safer in runtime.
- //
- // Use APLOG_INFO (as opposed to APLOG_TRACE1) as a mapping for
- // severity::trace. "LogLevel trace1" configuration directive switches
- // on the avalanche of log messages from various modules. Would be good
- // to avoid wading through them.
- //
- static int s[] = {APLOG_ERR, APLOG_WARNING, APLOG_INFO, APLOG_INFO};
-
- for (const auto& e: d)
- {
- string name;
-
- try
- {
- name = func_name (e.name);
- }
- catch (const invalid_argument&)
- {
- // Log "pretty" function description, see in log file & fix.
- name = e.name;
- }
-
- al->write (e.loc.file.c_str (),
- e.loc.line,
- name.c_str (),
- s[static_cast<size_t> (e.sev)],
- e.msg.c_str ());
- }
- }
- }
-
- void module::
- version (log& l)
- {
- log_ = &l;
- version ();
- }
-
- // module::name_value_scanner
- //
- module::name_value_scanner::
- name_value_scanner (const name_values& nv) noexcept
- : name_values_ (nv),
- i_ (nv.begin ()),
- name_ (true)
- {
- }
-
- bool module::name_value_scanner::
- more ()
- {
- return i_ != name_values_.end ();
- }
-
- const char* module::name_value_scanner::
- peek ()
- {
- if (i_ != name_values_.end ())
- return name_ ? i_->name.c_str () : i_->value->c_str ();
- else
- throw cli::eos_reached ();
- }
-
- const char* module::name_value_scanner::
- next ()
- {
- if (i_ != name_values_.end ())
- {
- const char* r (name_ ? i_->name.c_str () : i_->value->c_str ());
- skip ();
- return r;
- }
- else
- throw cli::eos_reached ();
- }
-
- void module::name_value_scanner::
- skip ()
- {
- if (i_ != name_values_.end ())
- {
- if (name_)
- {
- if (i_->value)
- name_ = false;
- else
- ++i_;
- }
- else
- {
- ++i_;
- name_ = true;
- }
- }
- else
- throw cli::eos_reached ();
- }
-}
diff --git a/brep/options-types b/brep/options-types
deleted file mode 100644
index 922637b..0000000
--- a/brep/options-types
+++ /dev/null
@@ -1,32 +0,0 @@
-// file : brep/options-types -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_OPTIONS_TYPES
-#define BREP_OPTIONS_TYPES
-
-#include <brep/types>
-#include <brep/utility>
-
-namespace brep
-{
- // brep types
- //
- enum class page_form
- {
- full,
- brief
- };
-
- struct page_menu
- {
- string label;
- string link;
-
- page_menu () = default;
- page_menu (string b, string l): label (move (b)), link (move (l)) {}
- };
-
-}
-
-#endif // BREP_OPTIONS_TYPES
diff --git a/brep/options.cli b/brep/options.cli
deleted file mode 100644
index d63a561..0000000
--- a/brep/options.cli
+++ /dev/null
@@ -1,211 +0,0 @@
-// file : brep/options.cli -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-include <web/xhtml-fragment>;
-
-include <brep/types>;
-
-include <brep/options-types>;
-
-namespace brep
-{
- // Web module configuration options.
- //
- namespace options
- {
- // Option groups.
- //
- class module
- {
- dir_path root = "/"
- {
- "<path>"
- "Repository root. That is, this is the part of the URL between the
- host name and the start of the repository. For example, root value
- '\cb{/pkg}' means the repository URL is http://example.org/pkg/.
- Specify '\cb{/}' to use the web server root (http://example.org/)."
- }
-
- uint16_t verbosity = 0
- {
- "<level>",
- "Trace verbosity level. Level 0 disables tracing, which is also the
- default."
- }
- };
-
- class db
- {
- string db-user
- {
- "<user>",
- "Database user name. If not specified, then operating system (login)
- name is used."
- }
-
- string db-password
- {
- "<pass>",
- "Database password. If not specified, then login without password is
- expected to work."
- }
-
- string db-name = "brep"
- {
- "<name>",
- "Database name. If not specified, then '\cb{brep}' is used by
- default."
- }
-
- string db-host
- {
- "<host>",
- "Database host name, address, or socket. If not specified, then
- connect to \cb{localhost} using the operating system-default
- mechanism (Unix-domain socket, etc)."
- }
-
- uint16_t db-port = 0
- {
- "<port>",
- "Database port number. If not specified, the default port is used."
- }
-
- size_t db-max-connections = 5
- {
- "<num>",
- "The maximum number of concurrent database connections per web server
- process. If 0, then no limitation is applied. The default is 5."
- }
-
- size_t db-retry = 10
- {
- "<num>",
- "The maximum number of times to retry database transactions in the
- face of recoverable failures (deadlock, loss of connection, etc). The
- default is 10."
- }
- };
-
- class page
- {
- web::xhtml::fragment logo
- {
- "<xhtml>",
- "Web page logo. It is displayed in the page header aligned to the left
- edge. The value is treated as an XHTML5 fragment."
- }
-
- vector<page_menu> menu;
- {
- "<label=link>",
- "Web page menu. Each entry is displayed in the page header in the
- order specified and aligned to the right edge. A link target that
- starts with '\cb{/}' or contains '\cb{:}' is used as is. Otherwise,
- it is prefixed with the repository web interface root."
- }
- };
-
- class search
- {
- uint16_t search-results = 10
- {
- "<num>",
- "Number of results per page. The default is 10."
- }
-
- uint16_t search-pages = 5
- {
- "<num>",
- "Number of pages in navigation (pager). The default is 5."
- }
- };
-
- class package
- {
- uint16_t package-description = 500
- {
- "<len>",
- "Number of package description characters to display in brief pages.
- The default is 500 (~ 80 characters * 6 lines)."
- }
-
- uint16_t package-changes = 5000;
- {
- "<len>",
- "Number of package changes characters to display in brief pages. The
- default is 5000 (~ 80 chars x 60 lines)."
- }
- };
-
- // Module options.
- //
- class package_search: search, db, page, module
- {
- };
-
- class package_details: package, search, db, page, module
- {
- };
-
- class package_version_details: package, db, page, module
- {
- };
-
- class repository_details: db, page, module
- {
- };
-
- class repository_root: module
- {
- };
- }
-
- // Web module HTTP request parameters.
- //
- namespace params
- {
- // Use parameters long names in the C++ code, short aliases (if present)
- // in HTTP URL.
- //
- class package_search
- {
- // Display package search result list starting from this page.
- //
- uint16_t page | p;
-
- // Package search criteria.
- //
- string query | q;
- };
-
- class package_details
- {
- // Display package version search result list starting from this page.
- //
- uint16_t page | p;
-
- // Package version search criteria.
- //
- string query | q;
-
- // Page form.
- //
- page_form form | f = page_form::brief;
- };
-
- class package_version_details
- {
- // Page form.
- //
- page_form form | f = page_form::brief;
- };
-
- class repository_details
- {
- // No parameters so far.
- //
- };
- }
-}
diff --git a/brep/page b/brep/page
deleted file mode 100644
index 512c11a..0000000
--- a/brep/page
+++ /dev/null
@@ -1,402 +0,0 @@
-// file : brep/page -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BREP_PAGE
-#define BREP_PAGE
-
-#include <xml/forward>
-
-#include <web/xhtml-fragment>
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/package>
-#include <brep/options-types> // page_menu
-
-namespace brep
-{
- // Page common building blocks.
- //
-
- // Generates CSS link elements.
- //
- class CSS_LINKS
- {
- public:
- CSS_LINKS (const path& p, const dir_path& r): path_ (p), root_ (r) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const path& path_;
- const dir_path& root_;
- };
-
- // Generates page header element.
- //
- class DIV_HEADER
- {
- public:
- DIV_HEADER (const dir_path& root,
- const web::xhtml::fragment& logo,
- const vector<page_menu>& menu):
- root_ (root), logo_ (logo), menu_ (menu) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const dir_path& root_;
- const web::xhtml::fragment& logo_;
- const vector<page_menu>& menu_;
- };
-
- // Generates package search form element.
- //
- class FORM_SEARCH
- {
- public:
- FORM_SEARCH (const string& q): query_ (q) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& query_;
- };
-
- // Generates counter element.
- //
- // It could be redunant to distinguish between singular and plural word forms
- // if it wouldn't be so cheap in English, and phrase '1 Packages' wouldn't
- // look that ugly.
- //
- class DIV_COUNTER
- {
- public:
- DIV_COUNTER (size_t c, const char* s, const char* p)
- : count_ (c), singular_ (s), plural_ (p) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- size_t count_;
- const char* singular_;
- const char* plural_;
- };
-
- // Generates package name element.
- //
- class TR_NAME
- {
- public:
- TR_NAME (const string& n, const string& q, const dir_path& r)
- : name_ (n), query_param_ (q), root_ (r) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& name_;
- const string& query_param_;
- const dir_path& root_;
- };
-
- // Generates package version element.
- //
- class TR_VERSION
- {
- public:
- // Display the version as a link to the package version details page.
- //
- TR_VERSION (const string& p, const string& v, const dir_path& r)
- : package_ (&p), version_ (v), root_ (&r) {}
-
- // Display the version as a regular text.
- //
- TR_VERSION (const string& v)
- : package_ (nullptr), version_ (v), root_ (nullptr) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string* package_;
- const string& version_;
- const dir_path* root_;
- };
-
- // Generates package summary element.
- //
- class TR_SUMMARY
- {
- public:
- TR_SUMMARY (const string& s): summary_ (s) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& summary_;
- };
-
- // Generates package license alternatives element.
- //
- class TR_LICENSE
- {
- public:
- TR_LICENSE (const license_alternatives& l): licenses_ (l) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const license_alternatives& licenses_;
- };
-
- // Generates package license alternatives elements. Differs from TR_LICENSE
- // by producing multiple rows instead of a single one.
- //
- class TR_LICENSES
- {
- public:
- TR_LICENSES (const license_alternatives& l): licenses_ (l) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const license_alternatives& licenses_;
- };
-
- // Generates package tags element.
- //
- class TR_TAGS
- {
- public:
- TR_TAGS (const strings& ts, const dir_path& r): tags_ (ts), root_ (r) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const strings& tags_;
- const dir_path& root_;
- };
-
- // Generates package dependencies element.
- //
- class TR_DEPENDS
- {
- public:
- TR_DEPENDS (const dependencies& d, const dir_path& r)
- : dependencies_ (d), root_ (r) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const dependencies& dependencies_;
- const dir_path& root_;
- };
-
- // Generates package requirements element.
- //
- class TR_REQUIRES
- {
- public:
- TR_REQUIRES (const requirements& r): requirements_ (r) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const requirements& requirements_;
- };
-
- // Generates url element.
- //
- class TR_URL
- {
- public:
- TR_URL (const url& u, const char* l = "url"): url_ (u), label_ (l) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const url& url_;
- const char* label_;
- };
-
- // Generates email element.
- //
- class TR_EMAIL
- {
- public:
- TR_EMAIL (const email& e, const char* l = "email")
- : email_ (e), label_ (l) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const email& email_;
- const char* label_;
- };
-
- // Generates package version priority element.
- //
- class TR_PRIORITY
- {
- public:
- TR_PRIORITY (const priority& p): priority_ (p) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const priority& priority_;
- };
-
- // Generates package location element.
- //
- class TR_LOCATION
- {
- public:
- TR_LOCATION (const string& n, const dir_path& r)
- : name_ (n), root_ (r) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& name_;
- const dir_path& root_;
- };
-
- // Generates package download URL element.
- //
- class TR_DOWNLOAD
- {
- public:
- TR_DOWNLOAD (const string& u): url_ (u) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& url_;
- };
-
- // Generates sha256sum element.
- //
- class TR_SHA256SUM
- {
- public:
- TR_SHA256SUM (const string& s): sha256sum_ (s) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& sha256sum_;
- };
-
- // Generates comment element.
- //
- class SPAN_COMMENT
- {
- public:
- SPAN_COMMENT (const string& c): comment_ (c) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& comment_;
- };
-
- // Generates package description element.
- //
- class P_DESCRIPTION
- {
- public:
- // Genereate full description.
- //
- P_DESCRIPTION (const string& d, const string& id = "")
- : description_ (d), length_ (d.size ()), url_ (nullptr), id_ (id) {}
-
- // Genereate brief description.
- //
- P_DESCRIPTION (const string& d, size_t l, const string& u)
- : description_ (d), length_ (l), url_ (&u) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& description_;
- size_t length_;
- const string* url_; // Full page url.
- string id_;
- };
-
- // Generates package description element.
- //
- class PRE_CHANGES
- {
- public:
- // Genereate full changes info.
- //
- PRE_CHANGES (const string& c)
- : changes_ (c), length_ (c.size ()), url_ (nullptr) {}
-
- // Genereate brief changes info.
- //
- PRE_CHANGES (const string& c, size_t l, const string& u)
- : changes_ (c), length_ (l), url_ (&u) {}
-
- void
- operator() (xml::serializer&) const;
-
- private:
- const string& changes_;
- size_t length_;
- const string* url_; // Full page url.
- };
-
- // Generates paging element.
- //
- class DIV_PAGER
- {
- public:
- DIV_PAGER (size_t current_page,
- size_t item_count,
- size_t item_per_page,
- size_t page_number_count,
- const string& url);
-
- void
- operator() (xml::serializer&) const;
-
- private:
- size_t current_page_;
- size_t item_count_;
- size_t item_per_page_;
- size_t page_number_count_;
- const string& url_;
- };
-
- // Convert the argument to a string representing the valid HTML 5 'id'
- // attribute value.
- //
- string
- html_id (const string&);
-}
-
-#endif // BREP_PAGE
diff --git a/brep/page.cxx b/brep/page.cxx
deleted file mode 100644
index 689ee20..0000000
--- a/brep/page.cxx
+++ /dev/null
@@ -1,693 +0,0 @@
-// file : brep/page.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/page>
-
-#include <set>
-#include <ios> // hex, uppercase, right
-#include <sstream>
-#include <iomanip> // setw(), setfill()
-#include <algorithm> // min()
-
-#include <xml/serializer>
-
-#include <web/xhtml>
-#include <web/mime-url-encoding>
-
-#include <brep/package>
-#include <brep/package-odb>
-
-using namespace std;
-using namespace xml;
-using namespace web;
-using namespace web::xhtml;
-
-namespace brep
-{
- // CSS_LINKS
- //
- void CSS_LINKS::
- operator() (serializer& s) const
- {
- static const path css ("@");
-
- s << *LINK(REL="stylesheet", TYPE="text/css", HREF=root_ / css / path_);
- }
-
- // DIV_HEADER
- //
- void DIV_HEADER::
- operator() (serializer& s) const
- {
- if (!logo_.empty () || !menu_.empty ())
- {
- s << DIV(ID="header-bar")
- << DIV(ID="header");
-
- if (!logo_.empty ())
- s << DIV(ID="header-logo") << logo_ << ~DIV;
-
- if (!menu_.empty ())
- {
- s << DIV(ID="header-menu")
- << DIV(ID="header-menu-body");
-
- for (const auto& m: menu_)
- {
- const string& l (m.link[0] == '/' || m.link.find (':') != string::npos
- ? m.link
- : root_.string () + m.link);
-
- s << A(HREF=l) << m.label << ~A;
- }
-
- s << ~DIV
- << ~DIV;
- }
-
- s << ~DIV
- << ~DIV;
- }
- }
-
- // FORM_SEARCH
- //
- void FORM_SEARCH::
- operator() (serializer& s) const
- {
- // The 'action' attribute is optional in HTML5. While the standard doesn't
- // specify browser behavior explicitly for the case the attribute is
- // ommited, the only reasonable behavior is to default it to the current
- // document URL.
- //
- s << FORM(ID="search")
- << TABLE(CLASS="form-table")
- << TBODY
- << TR
- << TD(ID="search-txt")
- << *INPUT(TYPE="search", NAME="q", VALUE=query_,
- AUTOFOCUS="autofocus")
- << ~TD
- << TD(ID="search-btn")
- << *INPUT(TYPE="submit", VALUE="Search")
- << ~TD
- << ~TR
- << ~TBODY
- << ~TABLE
- << ~FORM;
- }
-
- // DIV_COUNTER
- //
- void DIV_COUNTER::
- operator() (serializer& s) const
- {
- s << DIV(ID="count")
- << count_ << " "
- << (count_ % 10 == 1 && count_ % 100 != 11 ? singular_ : plural_)
- << ~DIV;
- }
-
- // TR_NAME
- //
- void TR_NAME::
- operator() (serializer& s) const
- {
- s << TR(CLASS="name")
- << TH << "name" << ~TH
- << TD
- << SPAN(CLASS="value")
- << A
- << HREF
-
- // Propagate search criteria to the package details page.
- //
- << root_ / path (mime_url_encode (name_)) << query_param_
-
- << ~HREF
- << name_
- << ~A
- << ~SPAN
- << ~TD
- << ~TR;
- }
-
- void TR_VERSION::
- operator() (serializer& s) const
- {
- s << TR(CLASS="version")
- << TH << "version" << ~TH
- << TD
- << SPAN(CLASS="value");
-
- if (package_ == nullptr)
- s << version_;
- else
- {
- assert (root_ != nullptr);
- s << A(HREF=*root_ / path (mime_url_encode (*package_)) / path (version_))
- << version_
- << ~A;
- }
-
- s << ~SPAN
- << ~TD
- << ~TR;
- }
-
- // TR_SUMMARY
- //
- void TR_SUMMARY::
- operator() (serializer& s) const
- {
- s << TR(CLASS="summary")
- << TH << "summary" << ~TH
- << TD << SPAN(CLASS="value") << summary_ << ~SPAN << ~TD
- << ~TR;
- }
-
- // TR_LICENSE
- //
- void TR_LICENSE::
- operator() (serializer& s) const
- {
- s << TR(CLASS="license")
- << TH << "license" << ~TH
- << TD
- << SPAN(CLASS="value");
-
- for (const auto& la: licenses_)
- {
- if (&la != &licenses_[0])
- s << " " << EM << "or" << ~EM << " ";
-
- bool m (la.size () > 1);
-
- if (m)
- s << "(";
-
- for (const auto& l: la)
- {
- if (&l != &la[0])
- s << " " << EM << "and" << ~EM << " ";
-
- s << l;
- }
-
- if (m)
- s << ")";
- }
-
- s << ~SPAN
- << ~TD
- << ~TR;
- }
-
- // TR_LICENSES
- //
- void TR_LICENSES::
- operator() (serializer& s) const
- {
- for (const auto& la: licenses_)
- {
- s << TR(CLASS="license")
- << TH << "license" << ~TH
- << TD
- << SPAN(CLASS="value");
-
- for (const auto& l: la)
- {
- if (&l != &la[0])
- s << " " << EM << "and" << ~EM << " ";
-
- s << l;
- }
-
- s << ~SPAN
- << SPAN_COMMENT (la.comment)
- << ~TD
- << ~TR;
- }
- }
-
- // TR_TAGS
- //
- void TR_TAGS::
- operator() (serializer& s) const
- {
- if (!tags_.empty ())
- {
- s << TR(CLASS="tags")
- << TH << "tags" << ~TH
- << TD
- << SPAN(CLASS="value");
-
- for (const auto& t: tags_)
- {
- if (&t != &tags_[0])
- s << " ";
-
- s << A << HREF << root_ << "?q=" << mime_url_encode (t) << ~HREF
- << t
- << ~A;
- }
-
- s << ~SPAN
- << ~TD
- << ~TR;
- }
- }
-
- // TR_DEPENDS
- //
- void TR_DEPENDS::
- operator() (serializer& s) const
- {
- s << TR(CLASS="depends")
- << TH << "depends" << ~TH
- << TD
- << SPAN(CLASS="value")
- << dependencies_.size ();
-
- if (!dependencies_.empty ())
- s << "; ";
-
- for (const auto& d: dependencies_)
- {
- if (&d != &dependencies_[0])
- s << ", ";
-
- if (d.conditional)
- s << "?";
-
- // Suppress package name duplicates.
- //
- set<string> names;
- for (const auto& da: d)
- names.emplace (da.name ());
-
- bool mult (names.size () > 1);
-
- if (mult)
- s << "(";
-
- bool first (true);
- for (const auto& da: d)
- {
- string n (da.name ());
- if (names.find (n) != names.end ())
- {
- names.erase (n);
-
- if (first)
- first = false;
- else
- s << " | ";
-
- shared_ptr<package> p (da.package.load ());
- assert (p->internal () || !p->other_repositories.empty ());
-
- shared_ptr<repository> r (
- p->internal ()
- ? p->internal_repository.load ()
- : p->other_repositories[0].load ());
-
- auto en (mime_url_encode (n));
-
- if (r->url)
- s << A(HREF=*r->url + en) << n << ~A;
- else if (p->internal ())
- s << A(HREF=root_ / path (en)) << n << ~A;
- else
- // Display the dependency as a plain text if no repository URL
- // available.
- //
- s << n;
- }
- }
-
- if (mult)
- s << ")";
- }
-
- s << ~SPAN
- << ~TD
- << ~TR;
- }
-
- // TR_REQUIRES
- //
- void TR_REQUIRES::
- operator() (serializer& s) const
- {
- // If there are no requirements, then we omit it, unlike depends, where we
- // show 0 explicitly.
- //
- if (requirements_.empty ())
- return;
-
- s << TR(CLASS="requires")
- << TH << "requires" << ~TH
- << TD
- << SPAN(CLASS="value")
- << requirements_.size () << "; ";
-
- for (const auto& r: requirements_)
- {
- if (&r != &requirements_[0])
- s << ", ";
-
- if (r.conditional)
- s << "?";
-
- if (r.empty ())
- {
- // If there is no requirement alternatives specified, then
- // print the comment first word.
- //
- const auto& c (r.comment);
- if (!c.empty ())
- {
- auto n (c.find (' '));
- s << string (c, 0, n);
-
- if (n != string::npos)
- s << "...";
- }
- }
- else
- {
- bool mult (r.size () > 1);
-
- if (mult)
- s << "(";
-
- for (const auto& ra: r)
- {
- if (&ra != &r[0])
- s << " | ";
-
- s << ra;
- }
-
- if (mult)
- s << ")";
- }
- }
-
- s << ~SPAN
- << ~TD
- << ~TR;
- }
-
- // TR_URL
- //
- void TR_URL::
- operator() (serializer& s) const
- {
- s << TR(CLASS=label_)
- << TH << label_ << ~TH
- << TD
- << SPAN(CLASS="value") << A(HREF=url_) << url_ << ~A << ~SPAN
- << SPAN_COMMENT (url_.comment)
- << ~TD
- << ~TR;
- }
-
- // TR_EMAIL
- //
- void TR_EMAIL::
- operator() (serializer& s) const
- {
- s << TR(CLASS=label_)
- << TH << label_ << ~TH
- << TD
- << SPAN(CLASS="value")
- << A(HREF="mailto:" + email_) << email_ << ~A
- << ~SPAN
- << SPAN_COMMENT (email_.comment)
- << ~TD
- << ~TR;
- }
-
- // TR_PRIORITY
- //
- void TR_PRIORITY::
- operator() (serializer& s) const
- {
- static const strings priority_names ({"low", "medium", "high", "security"});
- assert (priority_ < priority_names.size ());
-
- s << TR(CLASS="priority")
- << TH << "priority" << ~TH
- << TD
- << SPAN(CLASS="value") << priority_names[priority_] << ~SPAN
- << SPAN_COMMENT (priority_.comment)
- << ~TD
- << ~TR;
- }
-
- // TR_LOCATION
- //
- void TR_LOCATION::
- operator() (serializer& s) const
- {
- s << TR(CLASS="location")
- << TH << "location" << ~TH
- << TD
- << SPAN(CLASS="value")
- << A
- << HREF
- << root_ << "?about#" << mime_url_encode (html_id (name_))
- << ~HREF
- << name_
- << ~A
- << ~SPAN
- << ~TD
- << ~TR;
- }
-
- // TR_DOWNLOAD
- //
- void TR_DOWNLOAD::
- operator() (serializer& s) const
- {
- s << TR(CLASS="download")
- << TH << "download" << ~TH
- << TD
- << SPAN(CLASS="value") << A(HREF=url_) << url_ << ~A << ~SPAN
- << ~TD
- << ~TR;
- }
-
- // TR_SHA256SUM
- //
- void TR_SHA256SUM::
- operator() (serializer& s) const
- {
- s << TR(CLASS="sha256")
- << TH << "sha256" << ~TH
- << TD << SPAN(CLASS="value") << sha256sum_ << ~SPAN << ~TD
- << ~TR;
- }
-
- // SPAN_COMMENT
- //
- void SPAN_COMMENT::
- operator() (serializer& s) const
- {
- if (size_t l = comment_.size ())
- s << SPAN(CLASS="comment")
- << (comment_.back () == '.' ? string (comment_, 0, l - 1) : comment_)
- << ~SPAN;
- }
-
- // P_DESCRIPTION
- //
- void P_DESCRIPTION::
- operator() (serializer& s) const
- {
- if (description_.empty ())
- return;
-
- auto n (description_.find_first_of (" \t\n", length_));
- bool full (n == string::npos); // Description length is below the limit.
-
- // Truncate description if length exceed the limit.
- //
- const string& d (full ? description_ : string (description_, 0, n));
-
- // Format the description into paragraphs, recognizing a blank line as
- // paragraph separator, and replacing single newlines with a space.
- //
- s << P;
-
- if (!id_.empty ())
- s << ID(id_);
-
- bool nl (false); // The previous character is '\n'.
- for (const auto& c: d)
- {
- if (c == '\n')
- {
- if (nl)
- {
- s << ~P << P;
- nl = false;
- }
- else
- nl = true; // Delay printing until the next character.
- }
- else
- {
- if (nl)
- {
- s << ' '; // Replace the previous newline with a space.
- nl = false;
- }
-
- s << c;
- }
- }
-
- if (!full)
- {
- assert (url_ != nullptr);
- s << "... " << A(HREF=*url_) << "More" << ~A;
- }
-
- s << ~P;
- }
-
- // PRE_CHANGES
- //
- void PRE_CHANGES::
- operator() (serializer& s) const
- {
- if (changes_.empty ())
- return;
-
- auto n (changes_.find_first_of (" \t\n", length_));
- bool full (n == string::npos); // Changes length is below the limit.
-
- // Truncate changes if length exceed the limit.
- //
- const string& c (full ? changes_ : string (changes_, 0, n));
- s << PRE(ID="changes") << c;
-
- if (!full)
- {
- assert (url_ != nullptr);
- s << "... " << A(HREF=*url_) << "More" << ~A;
- }
-
- s << ~PRE;
- }
-
- // DIV_PAGER
- //
- DIV_PAGER::
- DIV_PAGER (size_t current_page,
- size_t item_count,
- size_t item_per_page,
- size_t page_number_count,
- const string& url)
- : current_page_ (current_page),
- item_count_ (item_count),
- item_per_page_ (item_per_page),
- page_number_count_ (page_number_count),
- url_ (url)
- {
- }
-
- void DIV_PAGER::
- operator() (serializer& s) const
- {
- if (item_count_ == 0 || item_per_page_ == 0)
- return;
-
- size_t pcount (item_count_ / item_per_page_); // Page count.
-
- if (item_count_ % item_per_page_)
- ++pcount;
-
- if (pcount > 1)
- {
- auto url (
- [this](size_t page) -> string
- {
- return page == 0
- ? url_
- : url_ + (url_.find ('?') == string::npos ? "?p=" : "&p=") +
- to_string (page);
- });
-
- s << DIV(ID="pager");
-
- if (current_page_ > 0)
- s << A(ID="prev", HREF=url (current_page_ - 1)) << "Prev" << ~A;
-
- if (page_number_count_)
- {
- size_t offset (page_number_count_ / 2);
- size_t from (current_page_ > offset ? current_page_ - offset : 0);
- size_t to (min (from + page_number_count_, pcount));
-
- for (size_t p (from); p < to; ++p)
- {
- s << A(HREF=url (p));
-
- if (p == current_page_)
- s << ID("curr");
-
- s << p + 1
- << ~A;
- }
- }
-
- if (current_page_ < pcount - 1)
- s << A(ID="next", HREF=url (current_page_ + 1)) << "Next" << ~A;
-
- s << ~DIV;
- }
- }
-
- // Convert the argument to a string conformant to the section
- // "3.2.5.1 The id attribute" of the HTML 5 specification at
- // http://www.w3.org/TR/html5/dom.html#the-id-attribute.
- //
- string
- html_id (const string& v)
- {
- ostringstream o;
- o << hex << uppercase << right << setfill ('0');
-
- // Replace space characters (as specified at
- // http://www.w3.org/TR/html5/infrastructure.html#space-character) with
- // the respective escape sequences.
- //
- for (auto c: v)
- {
- switch (c)
- {
- case ' ':
- case '\t':
- case '\n':
- case '\r':
- case '\f':
- case '~':
- {
- // We use '~' as an escape character because it doesn't require
- // escaping in URLs.
- //
- o << "~" << setw (2) << static_cast<unsigned short> (c);
- break;
- }
- default: o << c; break;
- }
- }
-
- return o.str ();
- }
-}
diff --git a/brep/services.cxx b/brep/services.cxx
deleted file mode 100644
index 94c7fc6..0000000
--- a/brep/services.cxx
+++ /dev/null
@@ -1,15 +0,0 @@
-// file : brep/services.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <ap_config.h> // AP_MODULE_DECLARE_DATA
-
-#include <web/apache/service>
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/mod-repository-root>
-
-static brep::repository_root mod;
-web::apache::service AP_MODULE_DECLARE_DATA brep_module ("brep", mod);
diff --git a/brep/types-parsers b/brep/types-parsers
deleted file mode 100644
index 78b7088..0000000
--- a/brep/types-parsers
+++ /dev/null
@@ -1,57 +0,0 @@
-// file : brep/types-parsers -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-// CLI parsers, included into the generated source files.
-//
-
-#ifndef BREP_TYPES_PARSERS
-#define BREP_TYPES_PARSERS
-
-#include <web/xhtml-fragment>
-
-#include <brep/types>
-#include <brep/utility>
-
-#include <brep/options-types>
-
-namespace brep
-{
- namespace cli
- {
- class scanner;
-
- template <typename T>
- struct parser;
-
- template <>
- struct parser<dir_path>
- {
- static void
- parse (dir_path&, scanner&);
- };
-
- template <>
- struct parser<page_form>
- {
- static void
- parse (page_form&, scanner&);
- };
-
- template <>
- struct parser<page_menu>
- {
- static void
- parse (page_menu&, scanner&);
- };
-
- template <>
- struct parser<web::xhtml::fragment>
- {
- static void
- parse (web::xhtml::fragment&, scanner&);
- };
- }
-}
-
-#endif // BREP_TYPES_PARSERS
diff --git a/brep/types-parsers.cxx b/brep/types-parsers.cxx
deleted file mode 100644
index 67f4812..0000000
--- a/brep/types-parsers.cxx
+++ /dev/null
@@ -1,114 +0,0 @@
-// file : brep/types-parsers.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <brep/types-parsers>
-
-#include <brep/options>
-
-using namespace std;
-using namespace web::xhtml;
-
-namespace brep
-{
- namespace cli
- {
- // Parse path.
- //
- template <typename T>
- static void
- parse_path (T& x, scanner& s)
- {
- const char* o (s.next ());
-
- if (!s.more ())
- throw missing_value (o);
-
- const char* v (s.next ());
-
- try
- {
- x = T (v);
- }
- catch (const invalid_path&)
- {
- throw invalid_value (o, v);
- }
- }
-
- void parser<dir_path>::
- parse (dir_path& x, scanner& s)
- {
- parse_path (x, s);
- }
-
- // Parse page_form.
- //
- void parser<page_form>::
- parse (page_form& x, scanner& s)
- {
- const char* o (s.next ());
-
- if (!s.more ())
- throw missing_value (o);
-
- const string v (s.next ());
- if (v == "full")
- x = page_form::full;
- else if (v == "brief")
- x = page_form::brief;
- else
- throw invalid_value (o, v);
- }
-
- // Parse page_menu.
- //
- void parser<page_menu>::
- parse (page_menu& x, scanner& s)
- {
- const char* o (s.next ());
-
- if (!s.more ())
- throw missing_value (o);
-
- const string v (s.next ());
-
- auto p (v.find ('='));
- if (p != string::npos)
- {
- string label (v, 0, p);
- string link (v, p + 1);
-
- if (!label.empty ())
- {
- x = page_menu (move (label), move (link));
- return;
- }
- }
-
- throw invalid_value (o, v);
- }
-
- // Parse web::xhtml::fragment.
- //
- void parser<fragment>::
- parse (fragment& x, scanner& s)
- {
- const char* o (s.next ());
-
- if (!s.more ())
- throw missing_value (o);
-
- const char* v (s.next ());
-
- try
- {
- x = fragment (v, o);
- }
- catch (const xml::parsing&)
- {
- throw invalid_value (o, v);
- }
- }
- }
-}