summaryrefslogtreecommitdiffstats
path: root/tools/localize/Perforce.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit54b6cfa9a9e5b861a9930af873580d6dc20f773c (patch)
tree35051494d2af230dce54d6b31c6af8fc24091316 /tools/localize/Perforce.cpp
downloadframeworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.zip
frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.gz
frameworks_base-54b6cfa9a9e5b861a9930af873580d6dc20f773c.tar.bz2
Initial Contribution
Diffstat (limited to 'tools/localize/Perforce.cpp')
-rw-r--r--tools/localize/Perforce.cpp228
1 files changed, 228 insertions, 0 deletions
diff --git a/tools/localize/Perforce.cpp b/tools/localize/Perforce.cpp
new file mode 100644
index 0000000..3184dfc
--- /dev/null
+++ b/tools/localize/Perforce.cpp
@@ -0,0 +1,228 @@
+#include "Perforce.h"
+#include "log.h"
+#include <sstream>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+using namespace std;
+
+extern char** environ;
+
+int
+Perforce::RunCommand(const string& cmd, string* result, bool printOnFailure)
+{
+ int err;
+ int outPipe[2];
+ int errPipe[2];
+ pid_t pid;
+
+ log_printf("Perforce::RunCommand: %s\n", cmd.c_str());
+
+ err = pipe(outPipe);
+ err |= pipe(errPipe);
+ if (err == -1) {
+ printf("couldn't create pipe. exiting.\n");
+ exit(1);
+ return -1;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ printf("couldn't fork. eixiting\n");
+ exit(1);
+ return -1;
+ }
+ else if (pid == 0) {
+ char const* args[] = {
+ "/bin/sh",
+ "-c",
+ cmd.c_str(),
+ NULL
+ };
+ close(outPipe[0]);
+ close(errPipe[0]);
+ dup2(outPipe[1], 1);
+ dup2(errPipe[1], 2);
+ execve(args[0], (char* const*)args, environ);
+ // done
+ }
+
+ close(outPipe[1]);
+ close(errPipe[1]);
+
+ result->clear();
+
+ char buf[1024];
+
+ // stdout
+ while (true) {
+ size_t amt = read(outPipe[0], buf, sizeof(buf));
+ result->append(buf, amt);
+ if (amt <= 0) {
+ break;
+ }
+ }
+
+ // stderr -- the messages are short so it ought to just fit in the buffer
+ string error;
+ while (true) {
+ size_t amt = read(errPipe[0], buf, sizeof(buf));
+ error.append(buf, amt);
+ if (amt <= 0) {
+ break;
+ }
+ }
+
+ close(outPipe[0]);
+ close(errPipe[0]);
+
+ waitpid(pid, &err, 0);
+ if (WIFEXITED(err)) {
+ err = WEXITSTATUS(err);
+ } else {
+ err = -1;
+ }
+ if (err != 0 && printOnFailure) {
+ write(2, error.c_str(), error.length());
+ }
+ return err;
+}
+
+int
+Perforce::GetResourceFileNames(const string& version, const string& base,
+ const vector<string>& apps, vector<string>* results,
+ bool printOnFailure)
+{
+ int err;
+ string text;
+ stringstream cmd;
+
+ cmd << "p4 files";
+
+ const size_t I = apps.size();
+ for (size_t i=0; i<I; i++) {
+ cmd << " \"" << base << '/' << apps[i] << "/res/values/strings.xml@" << version << '"';
+ }
+
+ err = RunCommand(cmd.str(), &text, printOnFailure);
+
+ const char* str = text.c_str();
+ while (*str) {
+ const char* lineend = strchr(str, '\n');
+ if (lineend == str) {
+ str++;
+ continue;
+ }
+ if (lineend-str > 1023) {
+ fprintf(stderr, "line too long!\n");
+ return 1;
+ }
+
+ string s(str, lineend-str);
+
+ char filename[1024];
+ char edit[1024];
+ int count = sscanf(str, "%[^#]#%*d - %s change %*d %*[^\n]\n", filename, edit);
+
+ if (count == 2 && 0 != strcmp("delete", edit)) {
+ results->push_back(string(filename));
+ }
+
+ str = lineend + 1;
+ }
+
+ return err;
+}
+
+int
+Perforce::GetFile(const string& file, const string& version, string* result,
+ bool printOnFailure)
+{
+ stringstream cmd;
+ cmd << "p4 print -q \"" << file << '@' << version << '"';
+ return RunCommand(cmd.str(), result, printOnFailure);
+}
+
+string
+Perforce::GetCurrentChange(bool printOnFailure)
+{
+ int err;
+ string text;
+
+ err = RunCommand("p4 changes -m 1 \\#have", &text, printOnFailure);
+ if (err != 0) {
+ return "";
+ }
+
+ long long n;
+ int count = sscanf(text.c_str(), "Change %lld on", &n);
+ if (count != 1) {
+ return "";
+ }
+
+ char result[100];
+ sprintf(result, "%lld", n);
+
+ return string(result);
+}
+
+static int
+do_files(const string& op, const vector<string>& files, bool printOnFailure)
+{
+ string text;
+ stringstream cmd;
+
+ cmd << "p4 " << op;
+
+ const size_t I = files.size();
+ for (size_t i=0; i<I; i++) {
+ cmd << " \"" << files[i] << "\"";
+ }
+
+ return Perforce::RunCommand(cmd.str(), &text, printOnFailure);
+}
+
+int
+Perforce::EditFiles(const vector<string>& files, bool printOnFailure)
+{
+ return do_files("edit", files, printOnFailure);
+}
+
+int
+Perforce::AddFiles(const vector<string>& files, bool printOnFailure)
+{
+ return do_files("add", files, printOnFailure);
+}
+
+int
+Perforce::DeleteFiles(const vector<string>& files, bool printOnFailure)
+{
+ return do_files("delete", files, printOnFailure);
+}
+
+string
+Perforce::Where(const string& depotPath, bool printOnFailure)
+{
+ int err;
+ string text;
+ string cmd = "p4 where ";
+ cmd += depotPath;
+
+ err = RunCommand(cmd, &text, printOnFailure);
+ if (err != 0) {
+ return "";
+ }
+
+ size_t index = text.find(' ');
+ if (index == text.npos) {
+ return "";
+ }
+ index = text.find(' ', index+1)+1;
+ if (index == text.npos) {
+ return "";
+ }
+
+ return text.substr(index, text.length()-index-1);
+}
+