X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=blobdiff_plain;f=src%2Fgromacs%2Fselection%2Fselectioncollection.cpp;h=bbe3f11df267e7b05191d1c847b3823bfb9ab351;hb=180cf1538ad2b19bd6b4108662adc4a519565fcb;hp=aba20c77174cc6c50f82f1c699634bca79431f06;hpb=1d597ac0415f9a847715ef65daa55fe1312bd59f;p=alexxy%2Fgromacs.git diff --git a/src/gromacs/selection/selectioncollection.cpp b/src/gromacs/selection/selectioncollection.cpp index aba20c7717..bbe3f11df2 100644 --- a/src/gromacs/selection/selectioncollection.cpp +++ b/src/gromacs/selection/selectioncollection.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #include "gromacs/fileio/trx.h" @@ -65,6 +66,7 @@ #include "gromacs/utility/gmxassert.h" #include "gromacs/utility/smalloc.h" #include "gromacs/utility/stringutil.h" +#include "gromacs/utility/textwriter.h" #include "compiler.h" #include "mempool.h" @@ -129,43 +131,44 @@ namespace /*! \brief * Reads a single selection line from stdin. * - * \param[in] infile Stream to read from (typically the StandardInputStream). - * \param[in] bInteractive Whether to print interactive prompts. + * \param[in] inputStream Stream to read from (typically the StandardInputStream). + * \param[in] statusWriter Stream to print prompts to (if NULL, no output is done). * \param[out] line The read line in stored here. * \returns true if something was read, false if at end of input. * * Handles line continuation, reading also the continuing line(s) in one call. */ -bool promptLine(TextInputStream *infile, bool bInteractive, std::string *line) +bool promptLine(TextInputStream *inputStream, TextWriter *statusWriter, + std::string *line) { - if (bInteractive) + if (statusWriter != NULL) { - fprintf(stderr, "> "); + statusWriter->writeString("> "); } - if (!infile->readLine(line)) + if (!inputStream->readLine(line)) { return false; } while (endsWith(*line, "\\\n")) { line->resize(line->length() - 2); - if (bInteractive) + if (statusWriter != NULL) { - fprintf(stderr, "... "); + statusWriter->writeString("... "); } std::string buffer; // Return value ignored, buffer remains empty and works correctly // if there is nothing to read. - infile->readLine(&buffer); + inputStream->readLine(&buffer); line->append(buffer); } if (endsWith(*line, "\n")) { line->resize(line->length() - 1); } - else if (bInteractive) + else if (statusWriter != NULL) { - fprintf(stderr, "\n"); + statusWriter->writeLine(); } return true; } @@ -216,6 +219,7 @@ int runParserLoop(yyscan_t scanner, _gmx_sel_yypstate *parserState, /*! \brief * Print current status in response to empty line in interactive input. * + * \param[in] writer Writer to use for the output. * \param[in] sc Selection collection data structure. * \param[in] grps Available index groups. * \param[in] firstSelection Index of first selection from this interactive @@ -227,52 +231,54 @@ int runParserLoop(yyscan_t scanner, _gmx_sel_yypstate *parserState, * * Prints the available index groups and currently provided selections. */ -void printCurrentStatus(gmx_ana_selcollection_t *sc, gmx_ana_indexgrps_t *grps, - size_t firstSelection, int maxCount, - const std::string &context, bool bFirst) +void printCurrentStatus(TextWriter *writer, gmx_ana_selcollection_t *sc, + gmx_ana_indexgrps_t *grps, size_t firstSelection, + int maxCount, const std::string &context, bool bFirst) { if (grps != NULL) { - std::fprintf(stderr, "Available static index groups:\n"); - gmx_ana_indexgrps_print(stderr, grps, 0); + writer->writeLine("Available static index groups:"); + gmx_ana_indexgrps_print(writer, grps, 0); } - std::fprintf(stderr, "Specify "); + writer->writeString("Specify "); if (maxCount < 0) { - std::fprintf(stderr, "any number of selections"); + writer->writeString("any number of selections"); } else if (maxCount == 1) { - std::fprintf(stderr, "a selection"); + writer->writeString("a selection"); } else { - std::fprintf(stderr, "%d selections", maxCount); + writer->writeString(formatString("%d selections", maxCount)); } - std::fprintf(stderr, "%s%s:\n", - context.empty() ? "" : " ", context.c_str()); - std::fprintf(stderr, - "(one per line, for status/groups, 'help' for help%s)\n", - maxCount < 0 ? ", Ctrl-D to end" : ""); + writer->writeString(formatString("%s%s:\n", + context.empty() ? "" : " ", context.c_str())); + writer->writeString(formatString( + "(one per line, for status/groups, 'help' for help%s)\n", + maxCount < 0 ? ", Ctrl-D to end" : "")); if (!bFirst && (sc->nvars > 0 || sc->sel.size() > firstSelection)) { - std::fprintf(stderr, "Currently provided selections:\n"); + writer->writeLine("Currently provided selections:"); for (int i = 0; i < sc->nvars; ++i) { - std::fprintf(stderr, " %s\n", sc->varstrs[i]); + writer->writeString(formatString(" %s\n", sc->varstrs[i])); } for (size_t i = firstSelection; i < sc->sel.size(); ++i) { - std::fprintf(stderr, " %2d. %s\n", - static_cast(i - firstSelection + 1), - sc->sel[i]->selectionText()); + writer->writeString(formatString( + " %2d. %s\n", + static_cast(i - firstSelection + 1), + sc->sel[i]->selectionText())); } if (maxCount > 0) { const int remaining = maxCount - static_cast(sc->sel.size() - firstSelection); - std::fprintf(stderr, "(%d more selection%s required)\n", - remaining, remaining > 1 ? "s" : ""); + writer->writeString(formatString( + "(%d more selection%s required)\n", + remaining, remaining > 1 ? "s" : "")); } } } @@ -280,20 +286,21 @@ void printCurrentStatus(gmx_ana_selcollection_t *sc, gmx_ana_indexgrps_t *grps, /*! \brief * Prints selection help in interactive selection input. * + * \param[in] writer Writer to use for the output. * \param[in] sc Selection collection data structure. * \param[in] line Line of user input requesting help (starting with `help`). * * Initializes the selection help if not yet initialized, and finds the help * topic based on words on the input line. */ -void printHelp(gmx_ana_selcollection_t *sc, const std::string &line) +void printHelp(TextWriter *writer, gmx_ana_selcollection_t *sc, + const std::string &line) { if (sc->rootHelp.get() == NULL) { sc->rootHelp = createSelectionHelpTopic(); } - HelpWriterContext context(&TextOutputFile::standardError(), - eHelpOutputFormat_Console); + HelpWriterContext context(&writer->stream(), eHelpOutputFormat_Console); HelpManager manager(*sc->rootHelp, context); try { @@ -307,7 +314,7 @@ void printHelp(gmx_ana_selcollection_t *sc, const std::string &line) } catch (const InvalidInputError &ex) { - fprintf(stderr, "%s\n", ex.what()); + writer->writeLine(ex.what()); return; } manager.writeCurrentTopic(); @@ -317,8 +324,10 @@ void printHelp(gmx_ana_selcollection_t *sc, const std::string &line) * Helper function that runs the parser once the tokenizer has been * initialized. * - * \param[in,out] scanner Scanner data structure. - * \param[in] bStdIn Whether to use a line-based reading + * \param[in,out] scanner Scanner data structure. + * \param[in] inputStream Stream to use for input (currently only with + * `bInteractive==true`). + * \param[in] bInteractive Whether to use a line-based reading * algorithm designed for interactive input. * \param[in] maxnr Maximum number of selections to parse * (if -1, parse as many as provided by the user). @@ -327,11 +336,11 @@ void printHelp(gmx_ana_selcollection_t *sc, const std::string &line) * \throws std::bad_alloc if out of memory. * \throws InvalidInputError if there is a parsing error. * - * Used internally to implement parseFromStdin(), parseFromFile() and + * Used internally to implement parseInteractive(), parseFromFile() and * parseFromString(). */ -SelectionList runParser(yyscan_t scanner, bool bStdIn, int maxnr, - const std::string &context) +SelectionList runParser(yyscan_t scanner, TextInputStream *inputStream, + bool bInteractive, int maxnr, const std::string &context) { boost::shared_ptr scannerGuard(scanner, &_gmx_sel_free_lexer); gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner); @@ -341,30 +350,29 @@ SelectionList runParser(yyscan_t scanner, bool bStdIn, int maxnr, { boost::shared_ptr<_gmx_sel_yypstate> parserState( _gmx_sel_yypstate_new(), &_gmx_sel_yypstate_delete); - if (bStdIn) + if (bInteractive) { - TextInputStream &stdinFile(StandardInputStream::instance()); - const bool bInteractive = _gmx_sel_is_lexer_interactive(scanner); - if (bInteractive) + TextWriter *statusWriter = _gmx_sel_lexer_get_status_writer(scanner); + if (statusWriter != NULL) { - printCurrentStatus(sc, grps, oldCount, maxnr, context, true); + printCurrentStatus(statusWriter, sc, grps, oldCount, maxnr, context, true); } std::string line; int status; - while (promptLine(&stdinFile, bInteractive, &line)) + while (promptLine(inputStream, statusWriter, &line)) { - if (bInteractive) + if (statusWriter != NULL) { line = stripString(line); if (line.empty()) { - printCurrentStatus(sc, grps, oldCount, maxnr, context, false); + printCurrentStatus(statusWriter, sc, grps, oldCount, maxnr, context, false); continue; } if (startsWith(line, "help") && (line[4] == 0 || std::isspace(line[4]))) { - printHelp(sc, line); + printHelp(statusWriter, sc, line); continue; } } @@ -673,17 +681,31 @@ SelectionCollection::requiresTopology() const return false; } - SelectionList -SelectionCollection::parseFromStdin(int nr, bool bInteractive, +SelectionCollection::parseFromStdin(int count, bool bInteractive, const std::string &context) +{ + return parseInteractive(count, &StandardInputStream::instance(), + bInteractive ? &TextOutputFile::standardError() : NULL, + context); +} + +SelectionList +SelectionCollection::parseInteractive(int count, + TextInputStream *inputStream, + TextOutputStream *statusStream, + const std::string &context) { yyscan_t scanner; - _gmx_sel_init_lexer(&scanner, &impl_->sc_, bInteractive, nr, - impl_->bExternalGroupsSet_, - impl_->grps_); - return runParser(scanner, true, nr, context); + boost::scoped_ptr statusWriter; + if (statusStream != NULL) + { + statusWriter.reset(new TextWriter(statusStream)); + } + _gmx_sel_init_lexer(&scanner, &impl_->sc_, statusWriter.get(), + count, impl_->bExternalGroupsSet_, impl_->grps_); + return runParser(scanner, inputStream, true, count, context); } @@ -696,11 +718,11 @@ SelectionCollection::parseFromFile(const std::string &filename) yyscan_t scanner; TextInputFile file(filename); // TODO: Exception-safe way of using the lexer. - _gmx_sel_init_lexer(&scanner, &impl_->sc_, false, -1, + _gmx_sel_init_lexer(&scanner, &impl_->sc_, NULL, -1, impl_->bExternalGroupsSet_, impl_->grps_); _gmx_sel_set_lex_input_file(scanner, file.handle()); - return runParser(scanner, false, -1, std::string()); + return runParser(scanner, NULL, false, -1, std::string()); } catch (GromacsException &ex) { @@ -717,11 +739,11 @@ SelectionCollection::parseFromString(const std::string &str) { yyscan_t scanner; - _gmx_sel_init_lexer(&scanner, &impl_->sc_, false, -1, + _gmx_sel_init_lexer(&scanner, &impl_->sc_, NULL, -1, impl_->bExternalGroupsSet_, impl_->grps_); _gmx_sel_set_lex_input_str(scanner, str.c_str()); - return runParser(scanner, false, -1, std::string()); + return runParser(scanner, NULL, false, -1, std::string()); }