| 285 | }; |
| 286 | |
| 287 | static void handleUrlsInComment(Generator& generator, llvm::StringRef rawString, int commentStart) |
| 288 | { |
| 289 | std::size_t pos = 0; |
| 290 | while ((pos = rawString.find("http", pos)) != llvm::StringRef::npos) { |
| 291 | int begin = pos; |
| 292 | pos +=4; |
| 293 | if (begin != 0 && llvm::StringRef(" \t/*[]()<>|:\"'{}").find(rawString[begin-1]) == llvm::StringRef::npos) { |
| 294 | // the URL need to be the first character, or follow a space or one of the character |
| 295 | continue; |
| 296 | } |
| 297 | if (rawString[pos] == 's') pos++; |
| 298 | if (!rawString.substr(pos).startswith("://")) |
| 299 | continue; |
| 300 | pos+=3; |
| 301 | // We have an URL |
| 302 | |
| 303 | llvm::StringRef urlChars = "-._~:/?#[]@!$&'()*+,;=%"; // chars valid in the URL |
| 304 | while(pos < rawString.size() && (std::isalnum(rawString[pos]) || |
| 305 | urlChars.find(rawString[pos]) != llvm::StringRef::npos)) |
| 306 | pos++; |
| 307 | |
| 308 | // don't end with a period |
| 309 | if (rawString[pos-1]=='.') pos--; |
| 310 | |
| 311 | // Don't end with a closing parenthese or bracket unless the URL contains an opening one |
| 312 | // (e.g. wikipedia urls) |
| 313 | auto candidate = rawString.substr(begin, pos-begin); |
| 314 | if (rawString[pos-1]==')' && candidate.find('(') == llvm::StringRef::npos) pos--; |
| 315 | if (rawString[pos-1]==']' && candidate.find('[') == llvm::StringRef::npos) pos--; |
| 316 | |
| 317 | // don't end with a period |
| 318 | if (rawString[pos-1]=='.') pos--; |
| 319 | |
| 320 | auto len = pos - begin; |
| 321 | generator.addTag("a", "href=\"" % rawString.substr(begin, len) % "\"", |
| 322 | commentStart+begin, len); |
| 323 | } |
| 324 | |
| 325 | } |
| 326 | |
| 327 | void CommentHandler::handleComment(Annotator &A, Generator& generator, clang::Sema &Sema, |
| 328 | const char *bufferStart, int commentStart, int len, |
no test coverage detected