Perforce.cpp revision 8a2b9083e364ffd46f56362d46af2aeb4718d325
154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "Perforce.h"
254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "log.h"
3b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project#include <string.h>
4b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project#include <stdlib.h>
554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <sstream>
654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <sys/types.h>
754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <unistd.h>
8862bfdba159580f825af563b8e283842e28d140cAlexey Zaytsev#include <stdlib.h>
9862bfdba159580f825af563b8e283842e28d140cAlexey Zaytsev#include <string.h>
1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <sys/wait.h>
118a2b9083e364ffd46f56362d46af2aeb4718d325Scott Tsai#include <cstdio>
1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectusing namespace std;
1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectextern char** environ;
1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint
1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectPerforce::RunCommand(const string& cmd, string* result, bool printOnFailure)
1954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
2054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int err;
2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int outPipe[2];
2254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int errPipe[2];
2354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    pid_t pid;
2454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    log_printf("Perforce::RunCommand: %s\n", cmd.c_str());
2654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    err = pipe(outPipe);
2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    err |= pipe(errPipe);
2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err == -1) {
3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        printf("couldn't create pipe. exiting.\n");
3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        exit(1);
3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return -1;
3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    pid = fork();
3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (pid == -1) {
3754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        printf("couldn't fork. eixiting\n");
3854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        exit(1);
3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return -1;
4054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    else if (pid == 0) {
4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        char const* args[] = {
4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            "/bin/sh",
4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            "-c",
4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            cmd.c_str(),
4654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            NULL
4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        };
4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        close(outPipe[0]);
4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        close(errPipe[0]);
5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        dup2(outPipe[1], 1);
5154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        dup2(errPipe[1], 2);
5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        execve(args[0], (char* const*)args, environ);
5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // done
5454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
5554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    close(outPipe[1]);
5754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    close(errPipe[1]);
5854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    result->clear();
6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    char buf[1024];
6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // stdout
6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (true) {
6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        size_t amt = read(outPipe[0], buf, sizeof(buf));
6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        result->append(buf, amt);
6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (amt <= 0) {
6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            break;
6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // stderr -- the messages are short so it ought to just fit in the buffer
7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string error;
7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (true) {
7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        size_t amt = read(errPipe[0], buf, sizeof(buf));
7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        error.append(buf, amt);
7754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (amt <= 0) {
7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            break;
7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    close(outPipe[0]);
8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    close(errPipe[0]);
8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    waitpid(pid, &err, 0);
8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (WIFEXITED(err)) {
8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        err = WEXITSTATUS(err);
8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        err = -1;
9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err != 0 && printOnFailure) {
9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        write(2, error.c_str(), error.length());
9354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return err;
9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint
9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectPerforce::GetResourceFileNames(const string& version, const string& base,
9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                const vector<string>& apps, vector<string>* results,
10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                bool printOnFailure)
10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int err;
10354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string text;
10454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    stringstream cmd;
10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    cmd << "p4 files";
10754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const size_t I = apps.size();
10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    for (size_t i=0; i<I; i++) {
11054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        cmd << " \"" << base << '/' << apps[i] << "/res/values/strings.xml@" << version << '"';
11154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    err = RunCommand(cmd.str(), &text, printOnFailure);
11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
11554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const char* str = text.c_str();
11654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (*str) {
11754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        const char* lineend = strchr(str, '\n');
11854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (lineend == str) {
11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            str++;
12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            continue;
12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (lineend-str > 1023) {
12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            fprintf(stderr, "line too long!\n");
12454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return 1;
12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        string s(str, lineend-str);
12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        char filename[1024];
13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        char edit[1024];
13154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int count = sscanf(str, "%[^#]#%*d - %s change %*d %*[^\n]\n", filename, edit);
13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (count == 2 && 0 != strcmp("delete", edit)) {
13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            results->push_back(string(filename));
13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
13654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
13754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        str = lineend + 1;
13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
13954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
14054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return err;
14154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
14354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint
14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectPerforce::GetFile(const string& file, const string& version, string* result,
14554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        bool printOnFailure)
14654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
14754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    stringstream cmd;
14854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    cmd << "p4 print -q \"" << file << '@' << version << '"';
14954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return RunCommand(cmd.str(), result, printOnFailure);
15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
15154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstring
15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectPerforce::GetCurrentChange(bool printOnFailure)
15454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int err;
15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string text;
15754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    err = RunCommand("p4 changes -m 1 \\#have", &text, printOnFailure);
15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err != 0) {
16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return "";
16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
16254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
16354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    long long n;
16454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int count = sscanf(text.c_str(), "Change %lld on", &n);
16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (count != 1) {
16654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return "";
16754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
16854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
16954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    char result[100];
17054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    sprintf(result, "%lld", n);
17154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
17254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return string(result);
17354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
17454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
17554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic int
17654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectdo_files(const string& op, const vector<string>& files, bool printOnFailure)
17754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
17854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string text;
17954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    stringstream cmd;
18054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    cmd << "p4 " << op;
18254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const size_t I = files.size();
18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    for (size_t i=0; i<I; i++) {
18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        cmd << " \"" << files[i] << "\"";
18654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return Perforce::RunCommand(cmd.str(), &text, printOnFailure);
18954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
19054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint
19254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectPerforce::EditFiles(const vector<string>& files, bool printOnFailure)
19354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
19454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return do_files("edit", files, printOnFailure);
19554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
19654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint
19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectPerforce::AddFiles(const vector<string>& files, bool printOnFailure)
19954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return do_files("add", files, printOnFailure);
20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint
20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectPerforce::DeleteFiles(const vector<string>& files, bool printOnFailure)
20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return do_files("delete", files, printOnFailure);
20754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstring
21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectPerforce::Where(const string& depotPath, bool printOnFailure)
21154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int err;
21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string text;
21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string cmd = "p4 where ";
21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    cmd += depotPath;
21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    err = RunCommand(cmd, &text, printOnFailure);
21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (err != 0) {
21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return "";
22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    size_t index = text.find(' ');
22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (index == text.npos) {
22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return "";
22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    index = text.find(' ', index+1)+1;
22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (index == text.npos) {
22854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return "";
22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return text.substr(index, text.length()-index-1);
23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
234