]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/AST/CommentBriefParser.cpp
Merge bmake-20120831 from vendor/NetBSD/bmake/dist.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / AST / CommentBriefParser.cpp
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 "clang/AST/CommentCommandTraits.h"
12 #include "llvm/ADT/StringSwitch.h"
13
14 namespace clang {
15 namespace comments {
16
17 namespace {
18 /// Convert all whitespace into spaces, remove leading and trailing spaces,
19 /// compress multiple spaces into one.
20 void cleanupBrief(std::string &S) {
21   bool PrevWasSpace = true;
22   std::string::iterator O = S.begin();
23   for (std::string::iterator I = S.begin(), E = S.end();
24        I != E; ++I) {
25     const char C = *I;
26     if (C == ' ' || C == '\n' || C == '\r' ||
27         C == '\t' || C == '\v' || C == '\f') {
28       if (!PrevWasSpace) {
29         *O++ = ' ';
30         PrevWasSpace = true;
31       }
32       continue;
33     } else {
34       *O++ = C;
35       PrevWasSpace = false;
36     }
37   }
38   if (O != S.begin() && *(O - 1) == ' ')
39     --O;
40
41   S.resize(O - S.begin());
42 }
43 } // unnamed namespace
44
45 BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :
46     L(L), Traits(Traits) {
47   // Get lookahead token.
48   ConsumeToken();
49 }
50
51 std::string BriefParser::Parse() {
52   std::string FirstParagraphOrBrief;
53   std::string ReturnsParagraph;
54   bool InFirstParagraph = true;
55   bool InBrief = false;
56   bool InReturns = false;
57
58   while (Tok.isNot(tok::eof)) {
59     if (Tok.is(tok::text)) {
60       if (InFirstParagraph || InBrief)
61         FirstParagraphOrBrief += Tok.getText();
62       else if (InReturns)
63         ReturnsParagraph += Tok.getText();
64       ConsumeToken();
65       continue;
66     }
67
68     if (Tok.is(tok::command)) {
69       StringRef Name = Tok.getCommandName();
70       if (Traits.isBriefCommand(Name)) {
71         FirstParagraphOrBrief.clear();
72         InBrief = true;
73         ConsumeToken();
74         continue;
75       }
76       if (Traits.isReturnsCommand(Name)) {
77         InReturns = true;
78         ReturnsParagraph += "Returns ";
79       }
80       // Block commands implicitly start a new paragraph.
81       if (Traits.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         FirstParagraphOrBrief += ' ';
92       else if (InReturns)
93         ReturnsParagraph += ' ';
94       ConsumeToken();
95
96       if (Tok.is(tok::newline)) {
97         ConsumeToken();
98         // We found a paragraph end.
99         InFirstParagraph = false;
100         InReturns = false;
101         if (InBrief)
102           break;
103       }
104       continue;
105     }
106
107     // We didn't handle this token, so just drop it.
108     ConsumeToken();
109   }
110
111   cleanupBrief(FirstParagraphOrBrief);
112   if (!FirstParagraphOrBrief.empty())
113     return FirstParagraphOrBrief;
114
115   cleanupBrief(ReturnsParagraph);
116   return ReturnsParagraph;
117 }
118
119 } // end namespace comments
120 } // end namespace clang
121
122