1 //===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "clang/AST/CommentBriefParser.h" 11 #include "llvm/ADT/StringSwitch.h" 12 13 namespace clang { 14 namespace comments { 15 16 namespace { 17 /// Convert all whitespace into spaces, remove leading and trailing spaces, 18 /// compress multiple spaces into one. 19 void cleanupBrief(std::string &S) { 20 bool PrevWasSpace = true; 21 std::string::iterator O = S.begin(); 22 for (std::string::iterator I = S.begin(), E = S.end(); 23 I != E; ++I) { 24 const char C = *I; 25 if (C == ' ' || C == '\n' || C == '\r' || 26 C == '\t' || C == '\v' || C == '\f') { 27 if (!PrevWasSpace) { 28 *O++ = ' '; 29 PrevWasSpace = true; 30 } 31 continue; 32 } else { 33 *O++ = C; 34 PrevWasSpace = false; 35 } 36 } 37 if (O != S.begin() && *(O - 1) == ' ') 38 --O; 39 40 S.resize(O - S.begin()); 41 } 42 43 bool isBlockCommand(StringRef Name) { 44 return llvm::StringSwitch<bool>(Name) 45 .Cases("brief", "short", true) 46 .Cases("result", "return", "returns", true) 47 .Cases("author", "authors", true) 48 .Case("pre", true) 49 .Case("post", true) 50 .Cases("param", "arg", true) 51 .Default(false); 52 } 53 } // unnamed namespace 54 55 std::string BriefParser::Parse() { 56 std::string Paragraph; 57 bool InFirstParagraph = true; 58 bool InBrief = false; 59 60 while (Tok.isNot(tok::eof)) { 61 if (Tok.is(tok::text)) { 62 if (InFirstParagraph || InBrief) 63 Paragraph += Tok.getText(); 64 ConsumeToken(); 65 continue; 66 } 67 68 if (Tok.is(tok::command)) { 69 StringRef Name = Tok.getCommandName(); 70 if (Name == "brief" || Name == "short") { 71 Paragraph.clear(); 72 InBrief = true; 73 ConsumeToken(); 74 continue; 75 } 76 // Block commands implicitly start a new paragraph. 77 if (isBlockCommand(Name)) { 78 // We found an implicit paragraph end. 79 InFirstParagraph = false; 80 if (InBrief) 81 break; 82 } 83 } 84 85 if (Tok.is(tok::newline)) { 86 if (InFirstParagraph || InBrief) 87 Paragraph += ' '; 88 ConsumeToken(); 89 90 if (Tok.is(tok::newline)) { 91 ConsumeToken(); 92 // We found a paragraph end. 93 InFirstParagraph = false; 94 if (InBrief) 95 break; 96 } 97 continue; 98 } 99 100 // We didn't handle this token, so just drop it. 101 ConsumeToken(); 102 } 103 104 cleanupBrief(Paragraph); 105 return Paragraph; 106 } 107 108 BriefParser::BriefParser(Lexer &L) : L(L) 109 { 110 // Get lookahead token. 111 ConsumeToken(); 112 } 113 114 } // end namespace comments 115 } // end namespace clang 116 117 118