1 //===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/AST/CommentBriefParser.h"
11 #include "clang/AST/CommentCommandTraits.h"
17 inline bool isWhitespace(char C) {
18 return C == ' ' || C == '\n' || C == '\r' ||
19 C == '\t' || C == '\f' || C == '\v';
22 /// Convert all whitespace into spaces, remove leading and trailing spaces,
23 /// compress multiple spaces into one.
24 void cleanupBrief(std::string &S) {
25 bool PrevWasSpace = true;
26 std::string::iterator O = S.begin();
27 for (std::string::iterator I = S.begin(), E = S.end();
30 if (isWhitespace(C)) {
41 if (O != S.begin() && *(O - 1) == ' ')
44 S.resize(O - S.begin());
47 bool isWhitespace(StringRef Text) {
48 for (StringRef::const_iterator I = Text.begin(), E = Text.end();
50 if (!isWhitespace(*I))
55 } // unnamed namespace
57 BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :
58 L(L), Traits(Traits) {
59 // Get lookahead token.
63 std::string BriefParser::Parse() {
64 std::string FirstParagraphOrBrief;
65 std::string ReturnsParagraph;
66 bool InFirstParagraph = true;
68 bool InReturns = false;
70 while (Tok.isNot(tok::eof)) {
71 if (Tok.is(tok::text)) {
72 if (InFirstParagraph || InBrief)
73 FirstParagraphOrBrief += Tok.getText();
75 ReturnsParagraph += Tok.getText();
80 if (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) {
81 const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
82 if (Info->IsBriefCommand) {
83 FirstParagraphOrBrief.clear();
88 if (Info->IsReturnsCommand) {
91 InFirstParagraph = false;
92 ReturnsParagraph += "Returns ";
96 // Block commands implicitly start a new paragraph.
97 if (Info->IsBlockCommand) {
98 // We found an implicit paragraph end.
99 InFirstParagraph = false;
105 if (Tok.is(tok::newline)) {
106 if (InFirstParagraph || InBrief)
107 FirstParagraphOrBrief += ' ';
109 ReturnsParagraph += ' ';
112 // If the next token is a whitespace only text, ignore it. Thus we allow
113 // two paragraphs to be separated by line that has only whitespace in it.
115 // We don't need to add a space to the parsed text because we just added
116 // a space for the newline.
117 if (Tok.is(tok::text)) {
118 if (isWhitespace(Tok.getText()))
122 if (Tok.is(tok::newline)) {
124 // We found a paragraph end. This ends the brief description if
125 // \\brief command or its equivalent was explicitly used.
126 // Stop scanning text because an explicit \\brief paragraph is the
130 // End first paragraph if we found some non-whitespace text.
131 if (InFirstParagraph && !isWhitespace(FirstParagraphOrBrief))
132 InFirstParagraph = false;
133 // End the \\returns paragraph because we found the paragraph end.
139 // We didn't handle this token, so just drop it.
143 cleanupBrief(FirstParagraphOrBrief);
144 if (!FirstParagraphOrBrief.empty())
145 return FirstParagraphOrBrief;
147 cleanupBrief(ReturnsParagraph);
148 return ReturnsParagraph;
151 } // end namespace comments
152 } // end namespace clang