summaryrefslogtreecommitdiff
path: root/cli/usage.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'cli/usage.hxx')
-rw-r--r--cli/usage.hxx181
1 files changed, 181 insertions, 0 deletions
diff --git a/cli/usage.hxx b/cli/usage.hxx
new file mode 100644
index 0000000..3aeb30b
--- /dev/null
+++ b/cli/usage.hxx
@@ -0,0 +1,181 @@
+// file : cli/usage.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef CLI_USAGE_HXX
+#define CLI_USAGE_HXX
+
+#include <cstddef> // std::size_t
+#include <cstdlib> // std::abort
+
+#include <cutl/compiler/code-stream.hxx>
+
+template <typename C>
+class usage_indenter: public cutl::compiler::code_stream<C>
+{
+public:
+ usage_indenter (cutl::compiler::code_stream<C>& out)
+ : out_ (out),
+ option_length_ (0),
+ construct_ (con_newline)
+ {
+ }
+
+private:
+ usage_indenter (usage_indenter const&);
+
+ usage_indenter&
+ operator= (usage_indenter const&);
+
+public:
+ virtual void
+ put (C c)
+ {
+ switch (c)
+ {
+ case '\n':
+ {
+ switch (construct_)
+ {
+ case con_newline:
+ {
+ out_.put (c);
+ break;
+ }
+ case con_option:
+ {
+ construct_ = con_newline;
+ break;
+ }
+ case con_description:
+ {
+ out_.put (c);
+ construct_ = con_newline;
+ break;
+ }
+ default:
+ {
+ std::abort ();
+ }
+ }
+
+ break;
+ }
+ case '-':
+ {
+ switch (construct_)
+ {
+ case con_newline:
+ {
+ construct_ = con_option;
+ option_length_ = 0;
+ output_indentation ();
+ out_.put (c);
+ ++option_length_;
+ break;
+ }
+ case con_option:
+ {
+ ++option_length_;
+ //fall through
+ }
+ case con_description:
+ {
+ out_.put (c);
+ break;
+ }
+ default:
+ {
+ std::abort ();
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ switch (construct_)
+ {
+ case con_newline:
+ {
+ construct_ = con_description;
+ output_indentation ();
+ out_.put (c);
+ break;
+ }
+ case con_option:
+ {
+ ++option_length_;
+ //fall through
+ }
+ default:
+ {
+ out_.put (c);
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ virtual void
+ unbuffer ()
+ {
+ }
+
+private:
+ void
+ output_indentation ()
+ {
+ std::size_t spaces;
+
+ switch (construct_)
+ {
+ case con_option:
+ {
+ spaces = 2;
+ option_length_ += 2;
+ break;
+ }
+ case con_description:
+ {
+ spaces = 29;
+
+ if (option_length_)
+ {
+ if (option_length_ > spaces)
+ spaces = 1;
+ else
+ spaces -= option_length_;
+
+ option_length_ = 0;
+ }
+
+ break;
+ }
+ default:
+ {
+ std::abort ();
+ }
+ }
+
+ while (spaces--)
+ out_.put (' ');
+ }
+
+private:
+ cutl::compiler::code_stream<C>& out_;
+ size_t option_length_;
+
+ enum construct
+ {
+ con_newline,
+ con_option,
+ con_description
+ } construct_;
+};
+
+#endif // CLI_USAGE_HXX