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 .Case("brief", true) 46 .Case("result", true) 47 .Case("return", true) 48 .Case("returns", true) 49 .Case("author", true) 50 .Case("authors", true) 51 .Case("pre", true) 52 .Case("post", true) 53 .Case("param", true) 54 .Case("arg", true) 55 .Default(false); 56 } 57 } // unnamed namespace 58 59 std::string BriefParser::Parse() { 60 std::string Paragraph; 61 bool InFirstParagraph = true; 62 bool InBrief = false; 63 64 while (Tok.isNot(tok::eof)) { 65 if (Tok.is(tok::text)) { 66 if (InFirstParagraph || InBrief) 67 Paragraph += Tok.getText(); 68 ConsumeToken(); 69 continue; 70 } 71 72 if (Tok.is(tok::command)) { 73 StringRef Name = Tok.getCommandName(); 74 if (Name == "brief") { 75 Paragraph.clear(); 76 InBrief = true; 77 ConsumeToken(); 78 continue; 79 } 80 // Block commands implicitly start a new paragraph. 81 if (isBlockCommand(Name)) { 82 // We found an implicit paragraph end. 83 InFirstParagraph = false; 84 if (InBrief) 85 break; 86 } 87 } 88 89 if (Tok.is(tok::newline)) { 90 if (InFirstParagraph || InBrief) 91 Paragraph += ' '; 92 ConsumeToken(); 93 94 if (Tok.is(tok::newline)) { 95 ConsumeToken(); 96 // We found a paragraph end. 97 InFirstParagraph = false; 98 if (InBrief) 99 break; 100 } 101 continue; 102 } 103 104 // We didn't handle this token, so just drop it. 105 ConsumeToken(); 106 } 107 108 cleanupBrief(Paragraph); 109 return Paragraph; 110 } 111 112 BriefParser::BriefParser(Lexer &L) : L(L) 113 { 114 // Get lookahead token. 115 ConsumeToken(); 116 } 117 118 } // end namespace comments 119 } // end namespace clang 120 121 122