FileSpec.cpp revision 9c3cfe397d6040a46677e201c2682cc2a5163fe9
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <fcntl.h>
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <libgen.h>
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <stdlib.h>
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <sys/param.h>
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <sys/stat.h>
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <sys/types.h>
17a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham#include <pwd.h>
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <fstream>
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/FileSpec.h"
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataBufferHeap.h"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataBufferMemoryMap.h"
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace std;
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerGetFileStats (const FileSpec *file_spec, struct stat *stats_ptr)
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char resolved_path[PATH_MAX];
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (file_spec->GetPath(&resolved_path[0], sizeof(resolved_path)))
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return ::stat (resolved_path, stats_ptr) == 0;
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char*
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerGetCachedGlobTildeSlash()
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static std::string g_tilde;
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (g_tilde.empty())
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
45a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        struct passwd *user_entry;
46a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        user_entry = getpwuid(geteuid());
47a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        if (user_entry != NULL)
48a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham            g_tilde = user_entry->pw_dir;
49a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (g_tilde.empty())
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return NULL;
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return g_tilde.c_str();
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
56a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham// Resolves the username part of a path of the form ~user/other/directories, and
57a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham// writes the result into dst_path.
58a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham// Returns 0 if there WAS a ~ in the path but the username couldn't be resolved.
59a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham// Otherwise returns the number of characters copied into dst_path.  If the return
60a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham// is >= dst_len, then the resolved path is too long...
61a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Inghamint
62a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim InghamFileSpec::ResolveUsername (const char *src_path, char *dst_path, size_t dst_len)
63a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham{
64a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    char user_home[PATH_MAX];
65a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    const char *user_name;
66a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
67a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    if (src_path == NULL || src_path[0] == '\0')
68a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        return 0;
69b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton
70a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    // If there's no ~, then just copy src_path straight to dst_path (they may be the same string...)
71a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    if (src_path[0] != '~')
72a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    {
73a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        int len = strlen (src_path);
74a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        if (len >= dst_len)
75a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        {
76b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton            ::bcopy (src_path, dst_path, dst_len - 1);
77b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton            dst_path[dst_len] = '\0';
78a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        }
79a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        else
80b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton            ::bcopy (src_path, dst_path, len + 1);
81b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton
82a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        return len;
83a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    }
84a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
859c3cfe397d6040a46677e201c2682cc2a5163fe9Eli Friedman    const char *first_slash = ::strchr (src_path, '/');
86a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    char remainder[PATH_MAX];
87a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
88a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    if (first_slash == NULL)
89a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    {
90a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        // The whole name is the username (minus the ~):
91a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        user_name = src_path + 1;
92a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        remainder[0] = '\0';
93a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    }
94a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    else
95a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    {
96a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        int user_name_len = first_slash - src_path - 1;
97b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton        ::memcpy (user_home, src_path + 1, user_name_len);
98a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        user_home[user_name_len] = '\0';
99a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        user_name = user_home;
100a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
101b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton        ::strcpy (remainder, first_slash);
102a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    }
103b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton
104a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    if (user_name == NULL)
105a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        return 0;
106a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    // User name of "" means the current user...
107a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
108a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    struct passwd *user_entry;
109a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    const char *home_dir;
110a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
111a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    if (user_name[0] == '\0')
112a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    {
113a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        home_dir = GetCachedGlobTildeSlash();
114a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    }
115a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    else
116a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    {
117b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton        user_entry = ::getpwnam (user_name);
118a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        if (user_entry != NULL)
119a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham            home_dir = user_entry->pw_dir;
120a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    }
121a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
122a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    if (home_dir == NULL)
123a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        return 0;
124a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    else
125a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        return ::snprintf (dst_path, dst_len, "%s%s", home_dir, remainder);
126a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham}
127a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::Resolve (const char *src_path, char *dst_path, size_t dst_len)
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (src_path == NULL || src_path[0] == '\0')
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return 0;
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Glob if needed for ~/, otherwise copy in case src_path is same as dst_path...
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char unglobbed_path[PATH_MAX];
136a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    if (src_path[0] == '~')
137a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    {
138a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        int return_count = ResolveUsername(src_path, unglobbed_path, sizeof(unglobbed_path));
139a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham
140a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        // If we couldn't find the user referred to, or the resultant path was too long,
141a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        // then just copy over the src_path.
142a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham        if (return_count == 0 || return_count >= sizeof(unglobbed_path))
143a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham            ::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", src_path);
144a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham    }
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::snprintf(unglobbed_path, sizeof(unglobbed_path), "%s", src_path);
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Now resolve the path if needed
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char resolved_path[PATH_MAX];
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (::realpath (unglobbed_path, resolved_path))
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Success, copy the resolved path
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return ::snprintf(dst_path, dst_len, "%s", resolved_path);
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Failed, just copy the unglobbed path
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return ::snprintf(dst_path, dst_len, "%s", unglobbed_path);
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::FileSpec() :
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_directory(),
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_filename()
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Default constructor that can take an optional full path to a
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// file on disk.
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::FileSpec(const char *pathname) :
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_directory(),
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_filename()
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (pathname && pathname[0])
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SetFile(pathname);
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Copy constructor
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::FileSpec(const FileSpec& rhs) :
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_directory (rhs.m_directory),
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_filename (rhs.m_filename)
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Copy constructor
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::FileSpec(const FileSpec* rhs) :
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_directory(),
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_filename()
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (rhs)
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        *this = *rhs;
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Virtual destrcuctor in case anyone inherits from this class.
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::~FileSpec()
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Assignment operator.
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst FileSpec&
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::operator= (const FileSpec& rhs)
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (this != &rhs)
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_directory = rhs.m_directory;
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_filename = rhs.m_filename;
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return *this;
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Update the contents of this object with a new path. The path will
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// be split up into a directory and filename and stored as uniqued
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// string values for quick comparison and efficient memory usage.
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::SetFile(const char *pathname)
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_filename.Clear();
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_directory.Clear();
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (pathname == NULL || pathname[0] == '\0')
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char resolved_path[PATH_MAX];
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (FileSpec::Resolve (pathname, resolved_path, sizeof(resolved_path)) < sizeof(resolved_path) - 1)
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        char *filename = ::basename (resolved_path);
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (filename)
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_filename.SetCString (filename);
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Truncate the basename off the end of the resolved path
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Only attempt to get the dirname if it looks like we have a path
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (strchr(resolved_path, '/'))
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                char *directory = ::dirname (resolved_path);
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Make sure we didn't get our directory resolved to "." without having
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // specified
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (directory)
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    m_directory.SetCString(directory);
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    char *last_resolved_path_slash = strrchr(resolved_path, '/');
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (last_resolved_path_slash)
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        *last_resolved_path_slash = '\0';
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        m_directory.SetCString(resolved_path);
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_directory.SetCString(resolved_path);
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Convert to pointer operator. This allows code to check any FileSpec
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// objects to see if they contain anything valid using code such as:
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  if (file_spec)
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  {}
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::operator
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid*() const
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return (m_directory || m_filename) ? const_cast<FileSpec*>(this) : NULL;
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Logical NOT operator. This allows code to check any FileSpec
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// objects to see if they are invalid using code such as:
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  if (!file_spec)
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  {}
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::operator!() const
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return !m_directory && !m_filename;
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Equal to operator
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::operator== (const FileSpec& rhs) const
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_directory == rhs.m_directory && m_filename == rhs.m_filename;
30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Not equal to operator
30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::operator!= (const FileSpec& rhs) const
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_filename != rhs.m_filename || m_directory != rhs.m_directory;
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Less than operator
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::operator< (const FileSpec& rhs) const
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return FileSpec::Compare(*this, rhs, true) < 0;
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Dump a FileSpec object to a stream
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerStream&
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerlldb_private::operator << (Stream &s, const FileSpec& f)
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    f.Dump(&s);
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return s;
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Clear this object by releasing both the directory and filename
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// string values and making them both the empty string.
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::Clear()
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_directory.Clear();
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_filename.Clear();
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Compare two FileSpec objects. If "full" is true, then both
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the directory and the filename must match. If "full" is false,
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// then the directory names for "a" and "b" are only compared if
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// they are both non-empty. This allows a FileSpec object to only
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// contain a filename and it can match FileSpec objects that have
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// matching filenames with different paths.
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Return -1 if the "a" is less than "b", 0 if "a" is equal to "b"
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// and "1" if "a" is greater than "b".
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::Compare(const FileSpec& a, const FileSpec& b, bool full)
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int result = 0;
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // If full is true, then we must compare both the directory and filename.
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // If full is false, then if either directory is empty, then we match on
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // the basename only, and if both directories have valid values, we still
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // do a full compare. This allows for matching when we just have a filename
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // in one of the FileSpec objects.
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (full || (a.m_directory && b.m_directory))
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        result = ConstString::Compare(a.m_directory, b.m_directory);
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (result)
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return result;
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return ConstString::Compare (a.m_filename, b.m_filename);
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::Equal (const FileSpec& a, const FileSpec& b, bool full)
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (full)
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return a == b;
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return a.m_filename == b.m_filename;
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Dump the object to the supplied stream. If the object contains
38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// a valid directory name, it will be displayed followed by a
39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// directory delimiter, and the filename.
39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::Dump(Stream *s) const
39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_filename)
39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_directory.Dump(s, "");    // Provide a default for m_directory when we dump it in case it is invalid
39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_directory)
39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // If dirname was valid, then we need to print a slash between
40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // the directory and the filename
40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->PutChar('/');
40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_filename.Dump(s);
40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Returns true if the file exists.
40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::Exists () const
41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct stat file_stats;
41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return GetFileStats (this, &file_stats);
41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint64_t
41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::GetByteSize() const
41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct stat file_stats;
42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (GetFileStats (this, &file_stats))
42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return file_stats.st_size;
42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::FileType
42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::GetFileType () const
42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct stat file_stats;
43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (GetFileStats (this, &file_stats))
43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        mode_t file_type = file_stats.st_mode & S_IFMT;
43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (file_type)
43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case S_IFDIR:   return eFileTypeDirectory;
43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case S_IFIFO:   return eFileTypePipe;
43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case S_IFREG:   return eFileTypeRegular;
43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case S_IFSOCK:  return eFileTypeSocket;
43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case S_IFLNK:   return eFileTypeSymbolicLink;
44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return eFileTypeUknown;
44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return eFileTypeInvalid;
44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerTimeValue
44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::GetModificationTime () const
45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    TimeValue mod_time;
45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct stat file_stats;
45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (GetFileStats (this, &file_stats))
454b586901fb633b898e19bdfc8d605b4e89a3ab5b8Eli Friedman        mod_time.OffsetWithSeconds(file_stats.st_mtime);
45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return mod_time;
45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Directory string get accessor.
46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerConstString &
46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::GetDirectory()
46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_directory;
46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Directory string const get accessor.
46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
47024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst ConstString &
47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::GetDirectory() const
47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_directory;
47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Filename string get accessor.
47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerConstString &
48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::GetFilename()
48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_filename;
48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Filename string const get accessor.
48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst ConstString &
48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::GetFilename() const
49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_filename;
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Extract the directory and path into a fixed buffer. This is
49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// needed as the directory and path are stored in separate string
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// values.
49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::GetPath(char *path, size_t max_path_length) const
50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (max_path_length == 0)
50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    path[0] = '\0';
50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *dirname = m_directory.AsCString();
50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *filename = m_filename.AsCString();
50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (dirname)
50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (filename && filename[0])
51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return snprintf (path, max_path_length, "%s/%s", dirname, filename) < max_path_length;
51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            strncpy (path, dirname, max_path_length);
51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else if (filename)
52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        strncpy (path, filename, max_path_length);
52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
523dfe3df9af9bb7d8151a6a29cf957ebca90756b5dBenjamin Kramer    else
524dfe3df9af9bb7d8151a6a29cf957ebca90756b5dBenjamin Kramer    {
525dfe3df9af9bb7d8151a6a29cf957ebca90756b5dBenjamin Kramer        return false;
526dfe3df9af9bb7d8151a6a29cf957ebca90756b5dBenjamin Kramer    }
52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Any code paths that reach here assume that strncpy, or a similar function was called
52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // where any remaining bytes will be filled with NULLs and that the string won't be
53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // NULL terminated if it won't fit in the buffer.
53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // If the last character is NULL, then all went well
53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (path[max_path_length-1] == '\0')
53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Make sure the path is terminated, as it didn't fit into "path"
53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    path[max_path_length-1] = '\0';
53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Returns a shared pointer to a data buffer that contains all or
54324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// part of the contents of a file. The data is memory mapped and
54424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// will lazily page in data from the file as memory is accessed.
54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The data that is mappped will start "file_offset" bytes into the
54624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// file, and "file_size" bytes will be mapped. If "file_size" is
54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// greater than the number of bytes available in the file starting
54824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// at "file_offset", the number of bytes will be appropriately
54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// truncated. The final number of bytes that get mapped can be
55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// verified using the DataBuffer::GetByteSize() function.
55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDataBufferSP
55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::MemoryMapFileContents(off_t file_offset, size_t file_size) const
55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataBufferSP data_sp;
55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    auto_ptr<DataBufferMemoryMap> mmap_data(new DataBufferMemoryMap());
55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (mmap_data.get())
55824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
55924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (mmap_data->MemoryMapFromFileSpec (this, file_offset, file_size) >= file_size)
56024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            data_sp.reset(mmap_data.release());
56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return data_sp;
56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
56424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
56524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
56624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
56724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Return the size in bytes that this object takes in memory. This
56824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// returns the size in bytes of this object, not any shared string
56924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// values it may refer to.
57024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
57224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::MemorySize() const
57324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
57424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_filename.MemorySize() + m_directory.MemorySize();
57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
57624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
577704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton
578704363531ee4877ccc6d35d0702876096f54c67bGreg Claytonsize_t
579704363531ee4877ccc6d35d0702876096f54c67bGreg ClaytonFileSpec::ReadFileContents (off_t file_offset, void *dst, size_t dst_len) const
580704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton{
581704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton    size_t bytes_read = 0;
582704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton    char resolved_path[PATH_MAX];
583704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton    if (GetPath(resolved_path, sizeof(resolved_path)))
584704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton    {
585704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton        int fd = ::open (resolved_path, O_RDONLY, 0);
586704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton        if (fd != -1)
587704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton        {
588704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton            struct stat file_stats;
589704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton            if (::fstat (fd, &file_stats) == 0)
590704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton            {
591704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                // Read bytes directly into our basic_string buffer
592704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                if (file_stats.st_size > 0)
593704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                {
594704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                    off_t lseek_result = 0;
595704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                    if (file_offset > 0)
596704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                        lseek_result = ::lseek (fd, file_offset, SEEK_SET);
597704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton
598704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                    if (lseek_result == file_offset)
599704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                    {
600704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                        ssize_t n = ::read (fd, dst, dst_len);
601704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                        if (n >= 0)
602704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                            bytes_read = n;
603704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                    }
604704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                }
605704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton            }
606704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton        }
607704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton        close(fd);
608704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton    }
609704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton    return bytes_read;
610704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton}
611704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton
61224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
61324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Returns a shared pointer to a data buffer that contains all or
61424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// part of the contents of a file. The data copies into a heap based
61524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// buffer that lives in the DataBuffer shared pointer object returned.
61624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The data that is cached will start "file_offset" bytes into the
61724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// file, and "file_size" bytes will be mapped. If "file_size" is
61824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// greater than the number of bytes available in the file starting
61924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// at "file_offset", the number of bytes will be appropriately
62024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// truncated. The final number of bytes that get mapped can be
62124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// verified using the DataBuffer::GetByteSize() function.
62224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
62324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDataBufferSP
624704363531ee4877ccc6d35d0702876096f54c67bGreg ClaytonFileSpec::ReadFileContents (off_t file_offset, size_t file_size) const
62524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
62624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DataBufferSP data_sp;
62724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char resolved_path[PATH_MAX];
62824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (GetPath(resolved_path, sizeof(resolved_path)))
62924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
63024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int fd = ::open (resolved_path, O_RDONLY, 0);
63124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (fd != -1)
63224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
63324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            struct stat file_stats;
63424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (::fstat (fd, &file_stats) == 0)
63524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
63624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (file_stats.st_size > 0)
63724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
63824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    off_t lseek_result = 0;
63924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (file_offset > 0)
64024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        lseek_result = ::lseek (fd, file_offset, SEEK_SET);
64124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
64224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (lseek_result < 0)
64324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
64424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        // Get error from errno
64524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
64624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else if (lseek_result == file_offset)
64724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
648704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                        const size_t bytes_left = file_stats.st_size - file_offset;
649704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                        size_t num_bytes_to_read = file_size;
650704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                        if (num_bytes_to_read > bytes_left)
651704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                            num_bytes_to_read = bytes_left;
652704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton
65324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        std::auto_ptr<DataBufferHeap> data_heap_ap;
654704363531ee4877ccc6d35d0702876096f54c67bGreg Clayton                        data_heap_ap.reset(new DataBufferHeap(num_bytes_to_read, '\0'));
65524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
65624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (data_heap_ap.get())
65724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
65824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            ssize_t bytesRead = ::read (fd, (void *)data_heap_ap->GetBytes(), data_heap_ap->GetByteSize());
65924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            if (bytesRead >= 0)
66024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
66124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                // Make sure we read exactly what we asked for and if we got
66224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                // less, adjust the array
66324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                if (bytesRead < data_heap_ap->GetByteSize())
66424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    data_heap_ap->SetByteSize(bytesRead);
66524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                data_sp.reset(data_heap_ap.release());
66624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
66724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
66824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
66924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
67024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
67124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
67224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        close(fd);
67324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
67424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return data_sp;
67524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
67624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
67724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
67824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerFileSpec::ReadFileLines (STLStringArray &lines)
67924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
68024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool ret_val = false;
68124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lines.clear();
68224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
68324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::string dir_str (m_directory.AsCString());
68424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::string file_str (m_filename.AsCString());
68524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::string full_name = dir_str + "/" + file_str;
68624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
68724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ifstream file_stream (full_name.c_str());
68824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
68924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (file_stream)
69024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
69124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::string line;
69224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (getline (file_stream, line))
69324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner          lines.push_back (line);
69424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ret_val = true;
69524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
69624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
69724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return ret_val;
69824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
699