15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- PathV3.inc ---------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/FileSystem.h>
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/Directory.h>
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/Path.h>
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cerrno>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <dirent.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stdio.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/stat.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/types.h>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stack>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <unistd.h>
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld{
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace sys{
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace fs{
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace detail{
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst char          separator = '/';
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst char          preferred_separator = '/';
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// return the last charactor being handled.
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t canonicalize(std::string& pathname)
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Variable Index //
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // SepTable - stack of result separators
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // LR(1) Algorithm //
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // traverse pPathName
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   if we meet '//', '///', '////', ...
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //     -> ignore it
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //     -> push current into stack
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //     -> jump to the next not '/'
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   if we meet '/./'
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //     -> ignore
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //     -> jump to the next not '/'
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   if we meet '/../'
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //     -> pop previous position of '/' P
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //     -> erase P+1 to now
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   if we meet other else
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //     -> go go go
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //   if we meet '/.../', '/..../', ... -> illegal
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pathname.empty())
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0;
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t handler = 0;
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::stack<size_t> slash_stack;
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  slash_stack.push(-1);
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while (handler < pathname.size()) {
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (separator == pathname[handler]) { // handler = 1st '/'
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      size_t next = handler + 1;
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (next >= pathname.size())
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return handler;
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      switch(pathname[next]) { // next = handler + 1;
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        case separator: { // '//'
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          while (next < pathname.size() && separator == pathname[next])
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            ++next;
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // next is the last not '/'
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          pathname.erase(handler, next - handler - 1);
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // handler is the first '/'
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          slash_stack.push(handler);
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          break;
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        case '.': { // '/.'
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          ++next; // next = handler + 2
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if (next >= pathname.size()) // '/.'
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            return handler;
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          switch (pathname[next]) {
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            case separator: { // '/./'
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              pathname.erase(handler, 2);
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              break;
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            }
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            case '.': { // '/..'
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              ++next; // next = handler + 3;
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              if (next >= pathname.size()) // '/..?'
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                return handler;
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              switch(pathname[next]) {
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                case separator: { // '/../'
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  handler = slash_stack.top();
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  slash_stack.pop();
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  pathname.erase(handler+1, next-handler);
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  if (static_cast<size_t>(-1) == handler) {
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    slash_stack.push(-1);
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                    handler = pathname.find_first_of(separator, handler);
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  }
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  break;
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                }
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                case '.': { // '/...', illegal
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  return handler;
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  break;
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                }
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                default : { // '/..a'
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  slash_stack.push(handler);
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  handler = pathname.find_first_of(separator, handler+3);
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                  break;
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                }
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              }
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              break;
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            }
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            default : { // '/.a'
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              slash_stack.push(handler);
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              handler = pathname.find_first_of(separator, handler+2);
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              break;
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            }
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          break;
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        default : { // '/a
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          slash_stack.push(handler);
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          handler = pathname.find_first_of(separator, handler+1);
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          break;
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else {
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      handler = pathname.find_first_of(separator, handler);
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return handler;
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool not_found_error(int perrno)
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return perrno == ENOENT || perrno == ENOTDIR;
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid status(const Path& p, FileStatus& pFileStatus)
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  struct stat path_stat;
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(stat(p.c_str(), &path_stat)!= 0)
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if(not_found_error(errno))
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    {
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pFileStatus.setType(FileNotFound);
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pFileStatus.setType(StatusError);
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if(S_ISDIR(path_stat.st_mode))
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(DirectoryFile);
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if(S_ISREG(path_stat.st_mode))
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(RegularFile);
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if(S_ISBLK(path_stat.st_mode))
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(BlockFile);
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if(S_ISCHR(path_stat.st_mode))
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(CharacterFile);
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if(S_ISFIFO(path_stat.st_mode))
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(FifoFile);
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if(S_ISSOCK(path_stat.st_mode))
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(SocketFile);
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(TypeUnknown);
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid symlink_status(const Path& p, FileStatus& pFileStatus)
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  struct stat path_stat;
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(lstat(p.c_str(), &path_stat)!= 0)
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  {
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if(errno == ENOENT || errno == ENOTDIR) // these are not errors
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    {
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pFileStatus.setType(FileNotFound);
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      pFileStatus.setType(StatusError);
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(S_ISREG(path_stat.st_mode))
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(RegularFile);
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(S_ISDIR(path_stat.st_mode))
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(DirectoryFile);
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(S_ISLNK(path_stat.st_mode))
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(SymlinkFile);
1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(S_ISBLK(path_stat.st_mode))
1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(BlockFile);
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(S_ISCHR(path_stat.st_mode))
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(CharacterFile);
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(S_ISFIFO(path_stat.st_mode))
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(FifoFile);
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(S_ISSOCK(path_stat.st_mode))
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(SocketFile);
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pFileStatus.setType(TypeUnknown);
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// read_dir - return true if we read one entry
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//  @return value -1: read error
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                 0: read the end
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                 1: success
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic int read_dir(intptr_t& pDir, std::string& pOutFilename)
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  errno = 0;
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  dirent *cur_dir = ::readdir(reinterpret_cast<DIR*>(pDir));
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == cur_dir && 0 != errno)
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return -1;
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // idx does not stay at the end, but all elements had beed put into cache.
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (NULL == cur_dir) {
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return 0;
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  llvm::StringRef name(cur_dir->d_name, strlen(cur_dir->d_name));
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if ((name.size() == 1 && name[0] == '.') ||
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      (name.size() == 2 && name[0] == '.' && name[1] == '.'))
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return read_dir(pDir, pOutFilename);
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // find a new directory
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pOutFilename.append(name.data(), name.size());
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 1;
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// directory_iterator_increment - increment function implementation
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//  iterator will call this function in two situations:
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//  1. All elements have been put into cache, and iterator stays at the end
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//     of cache. (a real end)
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//  2. Some but not all elements had beed put into cache, and we stoped.
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//     An iterator now is staying at the end of cache. (a temporal end)
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaomcld::sys::fs::PathCache::entry_type* bring_one_into_cache(DirIterator& pIter)
2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::sys::fs::PathCache::entry_type* entry = 0;
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::string path(pIter.m_pParent->m_Path.native());
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (read_dir(pIter.m_pParent->m_Handler, path)) {
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  case 1: {
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // read one
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bool exist = false;
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    entry = pIter.m_pParent->m_Cache.insert(path, exist);
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!exist)
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      entry->setValue(new Path(path));
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    break;
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  case 0:// meet real end
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pIter.m_pParent->m_CacheFull = true;
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    break;
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  default:
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  case -1:
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(std::string("Can't read directory: ")+
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             pIter.m_pParent->path().native());
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    break;
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return entry;
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid open_dir(Directory& pDir)
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pDir.m_Handler = reinterpret_cast<intptr_t>(opendir(pDir.path().c_str()));
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pDir.m_Handler == 0) {
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    errno = 0; // opendir() will set errno if it failed to open directory.
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pDir.m_CacheFull = true;
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return;
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // read one entry for advance the end element of the cache.
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::string path(pDir.path().native());
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  switch (read_dir(pDir.m_Handler, path)) {
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  case 1: {
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // find a new directory
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    bool exist = false;
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    mcld::sys::fs::PathCache::entry_type* entry = pDir.m_Cache.insert(path, exist);
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (!exist)
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      entry->setValue(new Path(path));
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return;
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  case 0:
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // FIXME: a warning function
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    pDir.m_CacheFull = true;
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return;
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  default:
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  case -1:
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(std::string("Can't read directory: ")+
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             pDir.path().native());
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid close_dir(Directory& pDir)
2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pDir.m_Handler)
2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    closedir(reinterpret_cast<DIR *>(pDir.m_Handler));
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  pDir.m_Handler = 0;
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid get_pwd(std::string& pPWD)
2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* pwd = (char*)malloc(PATH_MAX);
2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pPWD.assign(getcwd(pwd, PATH_MAX));
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  free(pwd);
2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of detail
2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of fs
2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of sys
2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
300