#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "distcc.h"
#include "trace.h"
#include "util.h"
#include "exitcode.h"
#include "cpp_dialect.h"
char * dcc_find_extension(char *sfile)
{
char *dot;
dot = strrchr(sfile, '.');
if (dot == NULL || dot[1] == '\0') {
return NULL;
}
return dot;
}
const char * dcc_find_basename(const char *sfile)
{
char *slash;
if (!sfile)
return sfile;
slash = strrchr(sfile, '/');
if (slash == NULL || slash[1] == '\0')
return sfile;
return slash+1;
}
static int dcc_set_file_extension(const char *sfile,
const char *new_ext,
char **ofile)
{
char *dot, *o;
o = strdup(sfile);
dot = dcc_find_extension((char *) o);
if (!dot) {
rs_log_error("couldn't find extension in \"%s\"", o);
return EXIT_DISTCC_FAILED;
}
if (strlen(dot) < strlen(new_ext)) {
rs_log_error("not enough space for new extension");
return EXIT_DISTCC_FAILED;
}
strcpy(dot, new_ext);
*ofile = o;
return 0;
}
const char * dcc_preproc_exten(const char *e)
{
if (e[0] != '.')
return NULL;
e++;
if (dcc_seen_opt_x) {
return dcc_opt_x_ext;
}
if (!strcmp(e, "i") || !strcmp(e, "c")) {
return ".i";
} else if (!strcmp(e, "c") || !strcmp(e, "cc")
|| !strcmp(e, "cpp") || !strcmp(e, "cxx")
|| !strcmp(e, "cp") || !strcmp(e, "c++")
|| !strcmp(e, "C") || !strcmp(e, "ii")) {
return ".ii";
} else if (!strcmp(e, "m") || !strcmp(e, "mi")) {
return ".mi";
} else if (!strcmp(e, "mm") || !strcmp(e, "M") || !strcmp(e, "mii")) {
return ".mii";
} else if(!strcmp(e,"mi") || !strcmp(e, "m")) {
return ".mi";
} else if(!strcmp(e,"mii") || !strcmp(e,"mm")
|| !strcmp(e,"M")) {
return ".mii";
} else if (!strcasecmp(e, "s")) {
return ".s";
} else {
return NULL;
}
}
int dcc_is_preprocessed(const char *sfile)
{
const char *dot, *ext;
dot = dcc_find_extension((char *) sfile);
if (!dot)
return 0;
ext = dot+1;
switch (ext[0]) {
#ifdef ENABLE_REMOTE_ASSEMBLE
case 's':
return !strcmp(ext, "s");
#endif
case 'i':
return !strcmp(ext, "i")
|| !strcmp(ext, "ii");
case 'm':
return !strcmp(ext, "mi")
|| !strcmp(ext, "mii");
default:
return 0;
}
}
int dcc_is_source(const char *sfile)
{
const char *dot, *ext;
dot = dcc_find_extension((char *) sfile);
if (!dot)
return 0;
ext = dot+1;
switch (ext[0]) {
case 'i':
return !strcmp(ext, "i")
|| !strcmp(ext, "ii");
case 'c':
return !strcmp(ext, "c")
|| !strcmp(ext, "cc")
|| !strcmp(ext, "cpp")
|| !strcmp(ext, "cxx")
|| !strcmp(ext, "cp")
|| !strcmp(ext, "c++");
case 'C':
return !strcmp(ext, "C");
case 'm':
return !strcmp(ext,"m")
|| !strcmp(ext,"mm")
|| !strcmp(ext,"mi")
|| !strcmp(ext,"mii");
case 'M':
return !strcmp(ext, "M");
#ifdef ENABLE_REMOTE_ASSEMBLE
case 's':
return !strcmp(ext, "s");
case 'S':
return !strcmp(ext, "S");
#endif
default:
return 0;
}
}
int dcc_is_object(const char *filename)
{
const char *dot;
dot = dcc_find_extension((char *) filename);
if (!dot)
return 0;
return !strcmp(dot, ".o");
}
int
dcc_source_needs_local(const char *filename)
{
const char *p;
p = dcc_find_basename(filename);
if (str_startswith("conftest.", p) || str_startswith("tmp.conftest.", p)) {
rs_trace("autoconf tests are run locally: %s", filename);
return EXIT_DISTCC_FAILED;
}
return 0;
}
int dcc_output_from_source(const char *sfile,
const char *out_extn,
char **ofile)
{
char *slash;
if ((slash = strrchr(sfile, '/')))
sfile = slash+1;
if (strlen(sfile) < 3) {
rs_log_error("source file %s is bogus", sfile);
return EXIT_DISTCC_FAILED;
}
return dcc_set_file_extension(sfile, out_extn, ofile);
}