⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 options_description.cpp

📁 C++的一个好库。。。现在很流行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    alts.push_back(m_options[found]->key(name));
                    alts.push_back(m_options[i]->key(name));
                    boost::throw_exception(ambiguous_option(name, alts));
                }
                else
                {
                    found = i;
                }
            }
        }
        if (found != -1) {
            return m_options[found].get();
        } else {
            return 0;
        }
    }

    BOOST_PROGRAM_OPTIONS_DECL
    std::ostream& operator<<(std::ostream& os, const options_description& desc)
    {
        desc.print(os);
        return os;
    }

    namespace {

        void format_paragraph(std::ostream& os,
                              std::string par,
                              unsigned first_column_width,
                              unsigned line_length)
        {                    
            // index of tab (if present) is used as additional indent relative
            // to first_column_width if paragrapth is spanned over multiple
            // lines if tab is not on first line it is ignored
            string::size_type par_indent = par.find('\t');

            if (par_indent == string::npos)
            {
                par_indent = 0;
            }
            else
            {
                // only one tab per paragraph allowed
                if (count(par.begin(), par.end(), '\t') > 1)
                {
                    boost::throw_exception(program_options::error(
                        "Only one tab per paragraph is allowed"));
                }
          
                // erase tab from string
                par.erase(par_indent, 1);

                // this assert may fail due to user error or 
                // environment conditions!
                assert(par_indent < (line_length - first_column_width));

                // ignore tab if not on first line
                if (par_indent >= (line_length - first_column_width))
                {
                    par_indent = 0;
                }            
            }
          
            if (par.size() < (line_length - first_column_width))
            {
                os << par;
            }
            else
            {
                string::const_iterator       line_begin = par.begin();
                const string::const_iterator par_end = par.end();

                bool first_line = true; // of current paragraph!
            
                unsigned indent = first_column_width;
            
                while (line_begin < par_end)  // paragraph lines
                {
                    if (!first_line)
                    {
                        // trimm leading single spaces
                        // if (firstchar == ' ') &&
                        //    ((exists(firstchar + 1) && (firstchar + 1 != ' '))
                        if ((*line_begin == ' ') &&
                            ((line_begin + 1 < par_end) &&
                             (*(line_begin + 1) != ' ')))
                        {
                            line_begin += 1;  // line_begin != line_end
                        }
                    }

                    string::const_iterator line_end;
                
                    if (line_begin + (line_length - indent) > par_end)
                    {
                        line_end = par_end;
                    }
                    else
                    {
                        line_end = line_begin + (line_length - indent);
                    }
            
                    // prevent chopped words
                    // if (lastchar != ' ') &&
                    //    ((exists(lastchar + 1) && (lastchar + 1 != ' '))
                    if ((*(line_end - 1) != ' ') &&
                        ((line_end < par_end) && (*line_end != ' ')))
                    {
                        // find last ' ' in the second half of the current paragraph line
                        string::const_iterator last_space =
                            find(reverse_iterator<string::const_iterator>(line_end - 1),
                                 reverse_iterator<string::const_iterator>(line_begin - 1),
                                 ' ')
                            .base();
                
                        if (last_space != line_begin - 1)
                        {                 
                            // is last_space within the second half ot the 
                            // current line
                            if (unsigned(distance(last_space, line_end)) < 
                                (line_length - indent) / 2)
                            {
                                line_end = last_space;
                            }
                        }                                                
                    } // prevent chopped words
             
                    // write line to stream
                    copy(line_begin, line_end, ostream_iterator<char>(os));
              
                    if (first_line)
                    {
                        indent = first_column_width + par_indent;
                        first_line = false;
                    }

                    // more lines to follow?
                    if (line_end != par_end)
                    {
                        os << '\n';
                
                        for(unsigned pad = indent; pad > 0; --pad)
                        {
                            os.put(' ');
                        }                                                        
                    }
              
                    // next line starts after of this line
                    line_begin = line_end;              
                } // paragraph lines
            }          
        }                              
        
        void format_description(std::ostream& os,
                                const std::string& desc, 
                                unsigned first_column_width,
                                unsigned line_length)
        {
            // we need to use one char less per line to work correctly if actual
            // console has longer lines
            assert(line_length > 1);
            if (line_length > 1)
            {
                --line_length;
            }

            // line_length must be larger than first_column_width
            // this assert may fail due to user error or environment conditions!
            assert(line_length > first_column_width);

            // Note: can't use 'tokenizer' as name of typedef -- borland
            // will consider subsequence uses of 'tokenizer' as uses of
            // boost::tokenizer, not typedef.
            typedef boost::tokenizer<boost::char_separator<char> > tok;
          
            tok paragraphs(
                desc,
                char_separator<char>("\n", "", boost::keep_empty_tokens));
          
            tok::const_iterator       par_iter = paragraphs.begin();                
            const tok::const_iterator par_end = paragraphs.end();

            while (par_iter != par_end)  // paragraphs
            {
                format_paragraph(os, *par_iter, first_column_width, 
                                 line_length);
            
                ++par_iter;
            
                // prepair next line if any
                if (par_iter != par_end)
                {
                    os << '\n';
              
                    for(unsigned pad = first_column_width; pad > 0; --pad)
                    {
                        os.put(' ');
                    }                    
                }            
            }  // paragraphs
        }
    
        void format_one(std::ostream& os, const option_description& opt, 
                        unsigned first_column_width, unsigned line_length)
        {
            stringstream ss;
            ss << "  " << opt.format_name() << ' ' << opt.format_parameter();
            
            // Don't use ss.rdbuf() since g++ 2.96 is buggy on it.
            os << ss.str();

            if (!opt.description().empty())
            {
                for(unsigned pad = first_column_width - ss.str().size(); 
                    pad > 0; 
                    --pad)
                {
                    os.put(' ');
                }
            
                format_description(os, opt.description(),
                                   first_column_width, line_length);
            }
        }
    }

    void 
    options_description::print(std::ostream& os) const
    {
        if (!m_caption.empty())
            os << m_caption << ":\n";

        /* Find the maximum width of the option column */
        unsigned width(23);
        unsigned i; // vc6 has broken for loop scoping
        for (i = 0; i < m_options.size(); ++i)
        {
            const option_description& opt = *m_options[i];
            stringstream ss;
            ss << "  " << opt.format_name() << ' ' << opt.format_parameter();
            width = (max)(width, static_cast<unsigned>(ss.str().size()));            
        }
        
        /* add an additional space to improve readability */
        ++width;
            
        /* The options formatting style is stolen from Subversion. */
        for (i = 0; i < m_options.size(); ++i)
        {
            if (belong_to_group[i])
                continue;

            const option_description& opt = *m_options[i];

            format_one(os, opt, width, m_line_length);

            os << "\n";
        }

        for (unsigned j = 0; j < groups.size(); ++j) {            
            os << "\n" << *groups[j];
        }
    }

}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -