10578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato/*
20578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * Copyright (C) 2016 The Android Open Source Project
30578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato *
40578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
50578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * you may not use this file except in compliance with the License.
60578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * You may obtain a copy of the License at
70578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato *
80578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
90578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato *
100578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * Unless required by applicable law or agreed to in writing, software
110578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
120578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * See the License for the specific language governing permissions and
140578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato * limitations under the License.
150578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato */
160578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
170578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include "util.h"
180578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
190578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <sys/types.h>
200578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <sys/stat.h>
210578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <dirent.h>
220578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <string.h>
230578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato#include <unistd.h>
240578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
250578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
260578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoFileInfo::FileInfo()
270578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
280578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    memset(this, 0, sizeof(FileInfo));
290578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
300578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
310578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoFileInfo::FileInfo(const FileInfo& that)
320578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
330578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    memcpy(this, &that, sizeof(FileInfo));
340578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
350578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
360578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoFileInfo::FileInfo(const string& filename)
370578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
380578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    struct stat st;
390578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    int err = stat(filename.c_str(), &st);
400578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (err != 0) {
410578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        memset(this, 0, sizeof(FileInfo));
420578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    } else {
430578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        exists = true;
440578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        mtime = st.st_mtime;
450578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        ctime = st.st_ctime;
460578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        size = st.st_size;
470578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
480578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
490578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
500578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratobool
510578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoFileInfo::operator==(const FileInfo& that) const
520578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
530578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return exists == that.exists
540578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            && mtime == that.mtime
550578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            && ctime == that.ctime
560578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            && size == that.size;
570578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
580578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
590578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratobool
600578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoFileInfo::operator!=(const FileInfo& that) const
610578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
620578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return exists != that.exists
630578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            || mtime != that.mtime
640578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            || ctime != that.ctime
650578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            || size != that.size;
660578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
670578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
680578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoFileInfo::~FileInfo()
690578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
700578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
710578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
720578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoTrackedFile::TrackedFile()
730578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    :filename(),
740578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato     fileInfo()
750578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
760578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
770578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
780578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoTrackedFile::TrackedFile(const TrackedFile& that)
790578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
800578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    filename = that.filename;
810578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    fileInfo = that.fileInfo;
820578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
830578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
840578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoTrackedFile::TrackedFile(const string& file)
850578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    :filename(file),
860578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato     fileInfo(file)
870578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
880578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
890578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
900578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoTrackedFile::~TrackedFile()
910578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
920578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
930578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
940578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratobool
950578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe OnoratoTrackedFile::HasChanged() const
960578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
970578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    FileInfo updated(filename);
980578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return !updated.exists || fileInfo != updated;
990578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1000578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1010578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratovoid
1020578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratoget_directory_contents(const string& name, map<string,FileInfo>* results)
1030578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1040578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    int err;
1050578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    DIR* dir = opendir(name.c_str());
1060578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (dir == NULL) {
1070578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return;
1080578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1090578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1100578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    dirent* entry;
1110578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    while ((entry = readdir(dir)) != NULL) {
1120578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
1130578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            continue;
1140578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1150578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (entry->d_type == DT_DIR) {
1160578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            string subdir = name + "/" + entry->d_name;
1170578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            get_directory_contents(subdir, results);
1180578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        } else if (entry->d_type == DT_LNK || entry->d_type == DT_REG) {
1190578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            string filename(name + "/" + entry->d_name);
1200578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            (*results)[filename] = FileInfo(filename);
1210578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1220578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1230578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1240578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    closedir(dir);
1250578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1260578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1270578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratobool
1280578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratodirectory_contents_differ(const map<string,FileInfo>& before, const map<string,FileInfo>& after)
1290578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1300578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (before.size() != after.size()) {
1310578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return true;
1320578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1330578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    map<string,FileInfo>::const_iterator b = before.begin();
1340578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    map<string,FileInfo>::const_iterator a = after.begin();
1350578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    while (b != before.end() && a != after.end()) {
1360578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (b->first != a->first) {
1370578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            return true;
1380578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1390578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (a->second != b->second) {
1400578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            return true;
1410578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1420578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        a++;
1430578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        b++;
1440578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1450578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return false;
1460578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1470578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1480578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratostring
1490578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratoescape_quotes(const char* str)
1500578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1510578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    string result;
1520578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    while (*str) {
1530578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (*str == '"') {
1540578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            result += '\\';
1550578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            result += '"';
1560578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        } else {
1570578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            result += *str;
1580578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
1590578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1600578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return result;
1610578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1620578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1630578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratostring
1640578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratoescape_for_commandline(const char* str)
1650578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1660578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (strchr(str, '"') != NULL || strchr(str, ' ') != NULL
1670578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            || strchr(str, '\t') != NULL) {
1680578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return escape_quotes(str);
1690578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    } else {
1700578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return str;
1710578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1720578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1730578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1740578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratostatic bool
1750578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratospacechr(char c)
1760578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1770578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return c == ' ' || c == '\t' || c == '\n' || c == '\r';
1780578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1790578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1800578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratostring
1810578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratotrim(const string& str)
1820578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1830578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    const ssize_t N = (ssize_t)str.size();
1840578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    ssize_t begin = 0;
1850578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    while (begin < N && spacechr(str[begin])) {
1860578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        begin++;
1870578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1880578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    ssize_t end = N - 1;
1890578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    while (end >= begin && spacechr(str[end])) {
1900578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        end--;
1910578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
1920578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return string(str, begin, end-begin+1);
1930578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
1940578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
1950578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratobool
1960578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratostarts_with(const string& str, const string& prefix)
1970578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
1980578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return str.compare(0, prefix.length(), prefix) == 0;
1990578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
2000578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2010578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratobool
2020578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratoends_with(const string& str, const string& suffix)
2030578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
2040578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (str.length() < suffix.length()) {
2050578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return false;
2060578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    } else {
2070578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return str.compare(str.length()-suffix.length(), suffix.length(), suffix) == 0;
2080578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
2090578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
2100578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2110578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratovoid
2120578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratosplit_lines(vector<string>* result, const string& str)
2130578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
2140578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    const int N = str.length();
2150578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    int begin = 0;
2160578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    int end = 0;
2170578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    for (; end < N; end++) {
2180578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        const char c = str[end];
2190578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        if (c == '\r' || c == '\n') {
2200578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            if (begin != end) {
2210578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato                result->push_back(string(str, begin, end-begin));
2220578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            }
2230578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato            begin = end+1;
2240578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        }
2250578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
2260578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (begin != end) {
2270578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        result->push_back(string(str, begin, end-begin));
2280578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
2290578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
2300578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2310578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratostring
2320578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onoratoread_file(const string& filename)
2330578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato{
2340578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    FILE* file = fopen(filename.c_str(), "r");
2350578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    if (file == NULL) {
2360578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato        return string();
2370578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    }
2380578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2390578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    fseek(file, 0, SEEK_END);
2400578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    int size = ftell(file);
2410578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    fseek(file, 0, SEEK_SET);
2420578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2430578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    char* buf = (char*)malloc(size);
2440578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    fread(buf, 1, size, file);
2450578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2460578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    string result(buf, size);
2470578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2480578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    free(buf);
2490578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    fclose(file);
2500578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2510578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato    return result;
2520578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato}
2530578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
2540578cbc6c527bc09a38a0fcd8b9642c25c8ea023Joe Onorato
255