String AbstractFileManager::makeRelative(const String& absolutePath, const String& referencePath) {
            if (!::wxIsAbsolutePath(absolutePath))
                return absolutePath;
            if (!::wxIsAbsolutePath(referencePath))
                return "";
            
            StringList absolutePathComponents = resolvePath(pathComponents(absolutePath));
            StringList referencePathComponents = resolvePath(pathComponents(referencePath));
            StringList relativePathComponents;

            if (!isDirectory(referencePath))
                referencePathComponents.pop_back();
            
            unsigned int i = 0;
            for (; i < (std::min)(absolutePathComponents.size(), referencePathComponents.size()); i++) {
                const String& absolutePathComponent = absolutePathComponents[i];
                const String& referencePathComponent = referencePathComponents[i];
                if (absolutePathComponent != referencePathComponent)
                    break;
            }
            
            for (unsigned int j = i; j < referencePathComponents.size(); j++)
                relativePathComponents.push_back("..");
            
            for (unsigned int j = i; j < absolutePathComponents.size(); j++)
                relativePathComponents.push_back(absolutePathComponents[j]);
            
            return joinComponents(relativePathComponents);
        }
 StringList AbstractFileManager::resolvePath(const StringList& pathComponents) {
     StringList cleanComponents;
     for (unsigned int i = 0; i < pathComponents.size(); i++) {
         const String& component = pathComponents[i];
         if (component != ".") {
             if (component == ".." && !cleanComponents.empty())
                 cleanComponents.pop_back();
             else
                 cleanComponents.push_back(component);
         }
     }
     return cleanComponents;
 }
String sanitizePath(const String &path)
{
  // Standardize slashes to POSIX style
  String fixedPath = posixPath(path);

  // Check if path is absolute
  bool isAbsolute = isAbsolutePath(fixedPath);

  // Tokenize path
  StringList pathComponents;
  std::size_t start = 0;
  do {
    std::size_t separator = (std::min)(fixedPath.find('/', start), fixedPath.length());
    String token = fixedPath.substr(start, separator - start);
    if (token.empty() || token == ".") {
      // a/./b -> a/b and a//b -> a/b
    } else if (token == "..") {
      if (pathComponents.empty()) {
        // ../a -> ../a
        // /../a -> /a
        if (!isAbsolute)
          pathComponents.push_back(token);
      } else {
        // ../../a -> ../../a
        // a/../c -> c
        if (pathComponents.back() == "..")
          pathComponents.push_back(token);
        else
          pathComponents.pop_back();
      }
    } else {
      pathComponents.push_back(token);
    }

    start = separator + 1;
  } while (start < path.length());

  // Figure out if we need to add a leading slash
  String prefix;
  if (strBeginsWith(fixedPath, "/"))
    prefix = "/";

  // Return reassembled path
  return prefix + joinStrings(pathComponents, "/");
}
Example #4
0
void SearchContext::searchProc()
{
    int id = searchID_;
    HANDLE findHandle = INVALID_HANDLE_VALUE;
    StringList paths;
    paths = params_.paths;
    RegexList filespecRegexes;
    pcre *matchRegex = NULL;

    directoriesSearched_ = 0;
    directoriesSkipped_ = 0;
    filesSearched_ = 0;
    filesSkipped_ = 0;
    filesWithHits_ = 0;
    linesWithHits_ = 0;
    hits_ = 0;

    unsigned int startTick = GetTickCount();

    bool filespecUsesRegexes = ((params_.flags & SF_FILESPEC_REGEXES) != 0);
    bool matchUsesRegexes    = ((params_.flags & SF_MATCH_REGEXES) != 0);

	delete pokeData_;
	pokeData_ = new PokeData;

    if(matchUsesRegexes)
    {
        const char *error;
        int erroffset;
        int flags = 0;
        if(!(params_.flags & SF_MATCH_CASE_SENSITIVE))
            flags |= PCRE_CASELESS;
        matchRegex = pcre_compile(params_.match.c_str(), flags, &error, &erroffset, NULL);
        if(!matchRegex)
        {
            MessageBox(window_, error, "Match Regex Error", MB_OK);
            goto cleanup;
        }
    }

    for(StringList::iterator it = params_.filespecs.begin(); it != params_.filespecs.end(); ++it)
    {
        std::string regexString = it->c_str();
        if(!filespecUsesRegexes)
            convertWildcard(regexString);

        int flags = 0;
        if(!(params_.flags & SF_FILESPEC_CASE_SENSITIVE))
            flags |= PCRE_CASELESS;

        const char *error;
        int erroffset;
        pcre *regex = pcre_compile(regexString.c_str(), flags, &error, &erroffset, NULL);
        if(regex)
            filespecRegexes.push_back(regex);
        else
        {
            MessageBox(window_, error, "Filespec Regex Error", MB_OK);
            goto cleanup;
        }
    }

    PostMessage(window_, WM_SEARCHCONTEXT_STATE, 1, 0);

    while(!paths.empty())
    {
        directoriesSearched_++;
        stopCheck();

        std::string currentSearchPath = paths.back();
        std::string currentSearchWildcard = currentSearchPath + "\\*";

        paths.pop_back();

        WIN32_FIND_DATA wfd;
        findHandle = FindFirstFile(currentSearchWildcard.c_str(), &wfd);
        if(findHandle == INVALID_HANDLE_VALUE)
            continue;

        while(FindNextFile(findHandle, &wfd))
        {
            stopCheck();
            bool isDirectory = ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);

            if((wfd.cFileName[0] == '.') || (wfd.cFileName[0] == 0))
            {
                if(isDirectory)
                    directoriesSkipped_++;
                else
                    filesSkipped_++;
                continue;
            }

            std::string filename = currentSearchPath;
            filename += "\\";
            filename += wfd.cFileName;

            if(isDirectory)
            {
                if(params_.flags & SF_RECURSIVE)
                    paths.push_back(filename);
            }
            else
            {
                if(searchFile(id, filename, filespecRegexes, matchRegex))
                {
                    filesSearched_++;
                }
                else
                {
                    filesSkipped_++;
                }
                poke(id, "", HighlightList(), 0, false);
            }
        }

        if(findHandle != INVALID_HANDLE_VALUE)
        {
            FindClose(findHandle);
        }
    }

cleanup:
    for(RegexList::iterator it = filespecRegexes.begin(); it != filespecRegexes.end(); ++it)
    {
        pcre_free(*it);
    }
    if(matchRegex)
        pcre_free(matchRegex);
    filespecRegexes.clear();
    if(!stop_)
    {
        unsigned int endTick = GetTickCount();
        char buffer[512];
        float sec = (endTick - startTick) / 1000.0f;
        const char *verb = "searched";
        if(params_.flags & SF_REPLACE)
            verb = "updated";
        sprintf(buffer, "\n%d hits in %d lines across %d files.\n%d directories scanned, %d files %s, %d files skipped (%3.3f sec)", 
            hits_,
            linesWithHits_,
            filesWithHits_,
            directoriesSearched_,
            filesSearched_,
            verb,
            filesSkipped_,
            sec);
        poke(id, buffer, HighlightList(), 0, true);
    }
    delete pokeData_;
	pokeData_ = NULL;
    PostMessage(window_, WM_SEARCHCONTEXT_STATE, 0, 0);
}