Jack Palevich bdb087c930 Add includes to enable host C++ tools to compile with GCC 4.4
Otherwise printf is undeclared. These files worked with earlier versions
of gcc because either cstdio or stdio.h was being included by some other
header file. But this was not guaranteed behavior, so with GCC 4.4 there
are errors. The fix is backwards compatible with earlier versions of GCC.

This change includes either <cstdio> or <stdio.h> whichever looks more
appropriate given the other headers included by the given source file.

Note, I'm using "GCC" to mean Gnu Compile Collection, as this problem is
specific to C++ source files. (Presumably a C++-specific header file
changed to no longer include cstdio.)
2009-06-24 19:01:27 -07:00

232 lines
4.9 KiB
C++

#include "Perforce.h"
#include "log.h"
#include <string.h>
#include <cstdio>
#include <stdlib.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);
}