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