Idioms
------
+* Declare variables as late as convenient, not necessarily at the beginning of
+ the scope.
* Use NULL to initialize null pointers.
* Don't use NULL when comparing pointers.
* Use format(), x_malloc() and friends instead of checking for memory
struct args *
args_init(int init_argc, char **init_args)
{
- struct args *args;
- int i;
- args = (struct args *)x_malloc(sizeof(struct args));
+ struct args *args = (struct args *)x_malloc(sizeof(struct args));
args->argc = 0;
args->argv = (char **)x_malloc(sizeof(char *));
args->argv[0] = NULL;
- for (i = 0; i < init_argc; i++) {
+ for (int i = 0; i < init_argc; i++) {
args_add(args, init_args[i]);
}
return args;
struct args *
args_init_from_string(const char *command)
{
- struct args *args;
char *p = x_strdup(command);
char *q = p;
char *word, *saveptr = NULL;
-
- args = args_init(0, NULL);
+ struct args *args = args_init(0, NULL);
while ((word = strtok_r(q, " \t\r\n", &saveptr))) {
args_add(args, word);
q = NULL;
struct args *
args_init_from_gcc_atfile(const char *filename)
{
- struct args *args;
- char *pos, *argtext, *argpos, *argbuf;
- char quoting;
-
- // Used to track quoting state; if \0, we are not inside quotes. Otherwise
- // stores the quoting character that started it, for matching the end quote.
- quoting = '\0';
-
+ char *argtext;
if (!(argtext = read_text_file(filename, 0))) {
return NULL;
}
- args = args_init(0, NULL);
- pos = argtext;
- argbuf = x_malloc(strlen(argtext) + 1);
- argpos = argbuf;
+ struct args *args = args_init(0, NULL);
+ char *pos = argtext;
+ char *argbuf = x_malloc(strlen(argtext) + 1);
+ char *argpos = argbuf;
+
+ // Used to track quoting state; if \0, we are not inside quotes. Otherwise
+ // stores the quoting character that started it, for matching the end quote.
+ char quoting = '\0';
while (1) {
switch (*pos) {
if (quoting) {
break;
}
- // Fall through.
+ // Fall through.
case '\0':
// End of token
void
args_insert(struct args *dest, int index, struct args *src, bool replace)
{
- int offset;
- int i;
-
// Adjustments made if we are replacing or shifting the element currently at
// dest->argv[index].
- offset = replace ? 1 : 0;
+ int offset = replace ? 1 : 0;
if (replace) {
free(dest->argv[index]);
if (replace) {
// Have to shift everything down by 1 since we replaced with an empty
// list.
- for (i = index; i < dest->argc; i++) {
+ for (int i = index; i < dest->argc; i++) {
dest->argv[i] = dest->argv[i + 1];
}
dest->argc--;
sizeof(char *));
// Shift arguments over.
- for (i = dest->argc; i >= index + offset; i--) {
+ for (int i = dest->argc; i >= index + offset; i--) {
dest->argv[i + src->argc - offset] = dest->argv[i];
}
// Copy the new arguments into place.
- for (i = 0; i < src->argc; i++) {
+ for (int i = 0; i < src->argc; i++) {
dest->argv[i + index] = src->argv[i];
}
void
args_free(struct args *args)
{
- int i;
if (!args) {
return;
}
- for (i = 0; i < args->argc; ++i) {
+ for (int i = 0; i < args->argc; ++i) {
if (args->argv[i]) {
free(args->argv[i]);
}
void
args_extend(struct args *args, struct args *to_append)
{
- int i;
- for (i = 0; i < to_append->argc; i++) {
+ for (int i = 0; i < to_append->argc; i++) {
args_add(args, to_append->argv[i]);
}
}
void
args_strip(struct args *args, const char *prefix)
{
- int i;
- for (i = 0; i < args->argc; ) {
+ for (int i = 0; i < args->argc; ) {
if (str_startswith(args->argv[i], prefix)) {
free(args->argv[i]);
memmove(&args->argv[i],
char *
args_to_string(struct args *args)
{
- char *result;
- char **p;
unsigned size = 0;
- int pos;
- for (p = args->argv; *p; p++) {
+ for (char **p = args->argv; *p; p++) {
size += strlen(*p) + 1;
}
- result = x_malloc(size + 1);
- pos = 0;
- for (p = args->argv; *p; p++) {
+
+ char *result = x_malloc(size + 1);
+ int pos = 0;
+ for (char **p = args->argv; *p; p++) {
pos += sprintf(&result[pos], "%s ", *p);
}
result[pos - 1] = '\0';
bool
args_equal(struct args *args1, struct args *args2)
{
- int i;
if (args1->argc != args2->argc) {
return false;
}
- for (i = 0; i < args1->argc; i++) {
+ for (int i = 0; i < args1->argc; i++) {
if (!str_eq(args1->argv[i], args2->argv[i])) {
return false;
}
static void
add_prefix(struct args *args, char *prefix_command)
{
- char *e;
- char *tok, *saveptr = NULL;
- struct args *prefix;
- int i;
-
if (str_eq(prefix_command, "")) {
return;
}
- prefix = args_init(0, NULL);
- e = x_strdup(prefix_command);
- for (tok = strtok_r(e, " ", &saveptr);
+ struct args *prefix = args_init(0, NULL);
+ char *e = x_strdup(prefix_command);
+ char *saveptr = NULL;
+ for (char *tok = strtok_r(e, " ", &saveptr);
tok;
tok = strtok_r(NULL, " ", &saveptr)) {
char *p;
free(e);
cc_log("Using command-line prefix %s", prefix_command);
- for (i = prefix->argc; i != 0; i--) {
+ for (int i = prefix->argc; i != 0; i--) {
args_add_prefix(args, prefix->argv[i-1]);
}
args_free(prefix);
static void
add_pending_tmp_file(const char *path)
{
- struct pending_tmp_file *e;
-
block_signals();
- e = x_malloc(sizeof(*e));
+ struct pending_tmp_file *e = x_malloc(sizeof(*e));
e->path = x_strdup(path);
e->next = pending_tmp_files;
pending_tmp_files = e;
static void
clean_up_internal_tempdir(void)
{
- DIR *dir;
- struct dirent *entry;
- struct stat st;
time_t now = time(NULL);
-
+ struct stat st;
if (x_stat(conf->cache_dir, &st) != 0 || st.st_mtime + 3600 >= now) {
// No cleanup needed.
return;
update_mtime(conf->cache_dir);
- dir = opendir(temp_dir());
+ DIR *dir = opendir(temp_dir());
if (!dir) {
return;
}
+ struct dirent *entry;
while ((entry = readdir(dir))) {
- char *path;
-
if (str_eq(entry->d_name, ".") || str_eq(entry->d_name, "..")) {
continue;
}
- path = format("%s/%s", temp_dir(), entry->d_name);
+ char *path = format("%s/%s", temp_dir(), entry->d_name);
if (x_lstat(path, &st) == 0 && st.st_mtime + 3600 < now) {
tmp_unlink(path);
}
static char *
get_path_in_cache(const char *name, const char *suffix)
{
- unsigned i;
- char *path;
- char *result;
-
- path = x_strdup(conf->cache_dir);
- for (i = 0; i < conf->cache_dir_levels; ++i) {
+ char *path = x_strdup(conf->cache_dir);
+ for (unsigned i = 0; i < conf->cache_dir_levels; ++i) {
char *p = format("%s/%c", path, name[i]);
free(path);
path = p;
}
- result = format("%s/%s%s", path, name + conf->cache_dir_levels, suffix);
+ char *result =
+ format("%s/%s%s", path, name + conf->cache_dir_levels, suffix);
free(path);
return result;
}
static void
remember_include_file(char *path, struct mdfour *cpp_hash, bool system)
{
-#ifdef _WIN32
- DWORD attributes;
-#endif
- struct mdfour fhash;
- struct stat st;
- char *source = NULL;
- size_t size;
- bool is_pch;
size_t path_len = strlen(path);
- char *canonical;
- size_t canonical_len;
- char *ignore;
- size_t ignore_len;
- size_t i;
-
if (path_len >= 2 && (path[0] == '<' && path[path_len - 1] == '>')) {
// Typically <built-in> or <command-line>.
goto ignore;
#ifdef _WIN32
// stat fails on directories on win32.
- attributes = GetFileAttributes(path);
+ DWORD attributes = GetFileAttributes(path);
if (attributes != INVALID_FILE_ATTRIBUTES &&
attributes & FILE_ATTRIBUTE_DIRECTORY) {
goto ignore;
}
#endif
+ struct stat st;
if (x_stat(path, &st) != 0) {
goto failure;
}
}
// Canonicalize path for comparison; clang uses ./header.h.
- canonical = path;
- canonical_len = path_len;
+ char *canonical = path;
+ size_t canonical_len = path_len;
if (canonical[0] == '.' && canonical[1] == '/') {
canonical += 2;
canonical_len -= 2;
}
- for (i = 0; i < ignore_headers_len; i++) {
- ignore = ignore_headers[i];
- ignore_len = strlen(ignore);
+ for (size_t i = 0; i < ignore_headers_len; i++) {
+ char *ignore = ignore_headers[i];
+ size_t ignore_len = strlen(ignore);
if (ignore_len > canonical_len) {
continue;
}
goto failure;
}
+ struct mdfour fhash;
hash_start(&fhash);
- is_pch = is_precompiled_header(path);
+ bool is_pch = is_precompiled_header(path);
if (is_pch) {
- struct file_hash pch_hash;
if (!hash_file(&fhash, path)) {
goto failure;
}
+ struct file_hash pch_hash;
hash_result_as_bytes(&fhash, pch_hash.hash);
pch_hash.size = fhash.totalN;
hash_delimiter(cpp_hash, "pch_hash");
hash_buffer(cpp_hash, pch_hash.hash, sizeof(pch_hash.hash));
}
- if (conf->direct_mode) {
- struct file_hash *h;
+ if (conf->direct_mode) {
if (!is_pch) { // else: the file has already been hashed.
- int result;
-
+ char *source = NULL;
+ size_t size;
if (st.st_size > 0) {
if (!read_file(path, st.st_size, &source, &size)) {
goto failure;
size = 0;
}
- result = hash_source_code_string(conf, &fhash, source, size, path);
+ int result = hash_source_code_string(conf, &fhash, source, size, path);
+ free(source);
if (result & HASH_SOURCE_CODE_ERROR
|| result & HASH_SOURCE_CODE_FOUND_TIME) {
goto failure;
}
}
- h = x_malloc(sizeof(*h));
+ struct file_hash *h = x_malloc(sizeof(*h));
hash_result_as_bytes(&fhash, h->hash);
h->size = fhash.totalN;
hashtable_insert(included_files, path, h);
free(path);
}
- free(source);
return;
failure:
// Fall through.
ignore:
free(path);
- free(source);
}
// Make a relative path from current working directory to path if path is under
static char *
make_relative_path(char *path)
{
- char *canon_path, *path_suffix = NULL;
- struct stat st;
-
if (str_eq(conf->base_dir, "") || !str_startswith(path, conf->base_dir)) {
return path;
}
// dirname(path) and assemble the path afterwards. We only bother to try
// canonicalizing one of these two paths since a compiler path argument
// typically only makes sense if path or dirname(path) exists.
+ char *path_suffix = NULL;
+ struct stat st;
if (stat(path, &st) != 0) {
// path doesn't exist.
- char *dir, *p;
- dir = dirname(path);
+ char *dir = dirname(path);
if (stat(dir, &st) != 0) {
// And neither does its parent directory, so no action to take.
free(dir);
}
free(dir);
path_suffix = basename(path);
- p = path;
+ char *p = path;
path = dirname(path);
free(p);
}
- canon_path = x_realpath(path);
+ char *canon_path = x_realpath(path);
if (canon_path) {
- char *relpath;
free(path);
- relpath = get_relative_path(get_current_working_dir(), canon_path);
+ char *relpath = get_relative_path(get_current_working_dir(), canon_path);
free(canon_path);
if (path_suffix) {
path = format("%s/%s", relpath, path_suffix);
process_preprocessed_file(struct mdfour *hash, const char *path)
{
char *data;
- char *p, *q, *r, *end;
size_t size;
-
if (!read_file(path, 0, &data, &size)) {
return false;
}
}
// Bytes between p and q are pending to be hashed.
- end = data + size;
- p = data;
- q = data;
+ char *p = data;
+ char *q = data;
+ char *end = data + size;
+
// There must be at least 7 characters (# 1 "x") left to potentially find an
// include file path.
while (q < end - 7) {
|| (q[1] == 'l' && q[2] == 'i' && q[3] == 'n' && q[4] == 'e'
&& q[5] == ' '))
&& (q == data || q[-1] == '\n')) {
- char *path;
- bool system;
-
// Workarounds for preprocessor linemarker bugs in GCC version 6.
if (q[2] == '3') {
if (str_startswith(q, "# 31 \"<command-line>\"\n")) {
q++;
}
// Look for preprocessor flags, after the "filename".
- system = false;
- r = q + 1;
+ bool system = false;
+ char *r = q + 1;
while (r < end && *r != '\n') {
- if (*r == '3') { // system header
+ if (*r == '3') { // System header.
system = true;
}
r++;
}
// p and q span the include file path.
- path = x_strndup(p, q - p);
+ char *inc_path = x_strndup(p, q - p);
if (!has_absolute_include_headers) {
- has_absolute_include_headers = is_absolute_path(path);
+ has_absolute_include_headers = is_absolute_path(inc_path);
}
- path = make_relative_path(path);
- remember_include_file(path, hash, system);
+ inc_path = make_relative_path(inc_path);
+ remember_include_file(inc_path, hash, system);
p = r;
} else {
q++;
static void
use_relative_paths_in_depfile(const char *depfile)
{
- FILE *f, *tmpf;
- char buf[10000];
- char *tmp_file;
- char *relpath;
- bool result = false;
- char *token, *saveptr;
-
if (str_eq(conf->base_dir, "")) {
cc_log("Base dir not set, skip using relative paths");
return; // nothing to do
return; // nothing to do
}
+ FILE *f;
f = fopen(depfile, "r");
if (!f) {
cc_log("Cannot open dependency file: %s (%s)", depfile, strerror(errno));
return;
}
- tmp_file = format("%s.tmp", depfile);
- tmpf = create_tmp_file(&tmp_file, "w");
+ char *tmp_file = format("%s.tmp", depfile);
+ FILE *tmpf = create_tmp_file(&tmp_file, "w");
+
+ bool result = false;
+ char buf[10000];
while (fgets(buf, sizeof(buf), f) && !ferror(tmpf)) {
- token = strtok_r(buf, " \t", &saveptr);
+ char *saveptr;
+ char *token = strtok_r(buf, " \t", &saveptr);
while (token) {
+ char *relpath;
if (is_absolute_path(token) && str_startswith(token, conf->base_dir)) {
relpath = make_relative_path(x_strdup(token));
result = true;
} else {
relpath = token;
}
- if (token != buf) { // this is a dependency file
+ if (token != buf) { // This is a dependency file.
fputc(' ', tmpf);
}
fputs(relpath, tmpf);
static void
put_file_in_cache(const char *source, const char *dest)
{
- int ret;
- struct stat st;
- bool do_link = conf->hard_link && !conf->compression;
-
assert(!conf->read_only);
assert(!conf->read_only_direct);
+ bool do_link = conf->hard_link && !conf->compression;
if (do_link) {
x_unlink(dest);
- ret = link(source, dest);
+ int ret = link(source, dest);
if (ret != 0) {
cc_log("Failed to link %s to %s: %s", source, dest, strerror(errno));
cc_log("Falling back to copying");
}
}
if (!do_link) {
- ret = copy_file(
+ int ret = copy_file(
source, dest, conf->compression ? conf->compression_level : 0);
if (ret != 0) {
cc_log("Failed to copy %s to %s: %s", source, dest, strerror(errno));
failed();
}
}
+
cc_log("Stored in cache: %s -> %s", source, dest);
+
+ struct stat st;
if (x_stat(dest, &st) != 0) {
stats_update(STATS_ERROR);
failed();
{
int ret;
bool do_link = conf->hard_link && !file_is_compressed(source);
-
if (do_link) {
x_unlink(dest);
ret = link(source, dest);
// Create or update the manifest file.
void update_manifest_file(void)
{
- struct stat st;
- size_t old_size = 0; // in bytes
-
if (!conf->direct_mode
|| !included_files
|| conf->read_only
return;
}
+ struct stat st;
+ size_t old_size = 0; // in bytes
if (stat(manifest_path, &st) == 0) {
old_size = file_size(&st);
}
static void
to_cache(struct args *args)
{
- char *tmp_stdout, *tmp_stderr, *tmp_cov;
- char *tmp_dwo = NULL;
- struct stat st;
- int status, tmp_stdout_fd, tmp_stderr_fd;
-
- tmp_stdout = format("%s.tmp.stdout", cached_obj);
- tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
- tmp_stderr = format("%s.tmp.stderr", cached_obj);
- tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+ char *tmp_stdout = format("%s.tmp.stdout", cached_obj);
+ int tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
+ char *tmp_stderr = format("%s.tmp.stderr", cached_obj);
+ int tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+ char *tmp_cov;
if (generating_coverage) {
char *tmp_aux;
// GCC has some funny rule about max extension length.
// GCC (at least 4.8 and 4.9) forms the .dwo file name by removing everything
// after (and including) the last "." from the object file name and then
// appending ".dwo".
+ char *tmp_dwo = NULL;
if (using_split_dwarf) {
char *base_name = remove_extension(output_obj);
tmp_dwo = format("%s.dwo", base_name);
}
cc_log("Running real compiler");
- status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
+ int status =
+ execute(args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
args_pop(args, 3);
+ struct stat st;
if (x_stat(tmp_stdout, &st) != 0) {
// The stdout file was removed - cleanup in progress? Better bail out.
stats_update(STATS_MISSING);
// Merge stderr from the preprocessor (if any) and stderr from the real
// compiler into tmp_stderr.
if (cpp_stderr) {
- int fd_cpp_stderr;
- int fd_real_stderr;
- int fd_result;
- char *tmp_stderr2;
-
- tmp_stderr2 = format("%s.2", tmp_stderr);
+ char *tmp_stderr2 = format("%s.2", tmp_stderr);
if (x_rename(tmp_stderr, tmp_stderr2)) {
cc_log("Failed to rename %s to %s: %s", tmp_stderr, tmp_stderr2,
strerror(errno));
failed();
}
- fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
+
+ int fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
if (fd_cpp_stderr == -1) {
cc_log("Failed opening %s: %s", cpp_stderr, strerror(errno));
failed();
}
- fd_real_stderr = open(tmp_stderr2, O_RDONLY | O_BINARY);
+
+ int fd_real_stderr = open(tmp_stderr2, O_RDONLY | O_BINARY);
if (fd_real_stderr == -1) {
cc_log("Failed opening %s: %s", tmp_stderr2, strerror(errno));
failed();
}
- fd_result = open(tmp_stderr, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+
+ int fd_result =
+ open(tmp_stderr, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
if (fd_result == -1) {
cc_log("Failed opening %s: %s", tmp_stderr, strerror(errno));
failed();
}
+
copy_fd(fd_cpp_stderr, fd_result);
copy_fd(fd_real_stderr, fd_result);
close(fd_cpp_stderr);
}
if (status != 0) {
- int fd;
cc_log("Compiler gave exit status %d", status);
stats_update(STATS_STATUS);
- fd = open(tmp_stderr, O_RDONLY | O_BINARY);
+ int fd = open(tmp_stderr, O_RDONLY | O_BINARY);
if (fd != -1) {
// We can output stderr immediately instead of rerunning the compiler.
copy_fd(fd, 2);
static struct file_hash *
get_object_name_from_cpp(struct args *args, struct mdfour *hash)
{
- char *input_base;
- char *tmp;
- char *path_stdout, *path_stderr;
- int status, path_stderr_fd;
- struct file_hash *result;
-
- // Limit the basename to 10 characters in order to cope with filesystem with
- // small maximum filename length limits.
- input_base = basename(input_file);
- tmp = strchr(input_base, '.');
- if (tmp) {
- *tmp = 0;
- }
- if (strlen(input_base) > 10) {
- input_base[10] = 0;
- }
+ time_of_compilation = time(NULL);
- path_stderr = format("%s/tmp.cpp_stderr", temp_dir());
- path_stderr_fd = create_tmp_fd(&path_stderr);
+ char *path_stderr = format("%s/tmp.cpp_stderr", temp_dir());
+ int path_stderr_fd = create_tmp_fd(&path_stderr);
add_pending_tmp_file(path_stderr);
- time_of_compilation = time(NULL);
-
+ char *path_stdout;
+ int status;
if (direct_i_file) {
// We are compiling a .i or .ii file - that means we can skip the cpp stage
// and directly form the correct i_tmpfile.
status = 0;
} else {
// Run cpp on the input file to obtain the .i.
- int path_stdout_fd;
+
+ // Limit the basename to 10 characters in order to cope with filesystem with
+ // small maximum filename length limits.
+ char *input_base = basename(input_file);
+ char *tmp = strchr(input_base, '.');
+ if (tmp) {
+ *tmp = 0;
+ }
+ if (strlen(input_base) > 10) {
+ input_base[10] = 0;
+ }
+
path_stdout = format("%s/%s.stdout", temp_dir(), input_base);
- path_stdout_fd = create_tmp_fd(&path_stdout);
+ int path_stdout_fd = create_tmp_fd(&path_stdout);
add_pending_tmp_file(path_stdout);
int args_added = 2;
hash_string(hash, "false");
}
- result = x_malloc(sizeof(*result));
+ struct file_hash *result = x_malloc(sizeof(*result));
hash_result_as_bytes(hash, result->hash);
result->size = hash->totalN;
return result;
static void
update_cached_result_globals(struct file_hash *hash)
{
- char *object_name;
- object_name = format_hash_as_string(hash->hash, hash->size);
+ char *object_name = format_hash_as_string(hash->hash, hash->size);
cached_obj_hash = hash;
cached_obj = get_path_in_cache(object_name, ".o");
cached_stderr = get_path_in_cache(object_name, ".stderr");
compiler_is_clang(struct args *args)
{
char *name = basename(args->argv[0]);
- bool is = strstr(name, "clang") != NULL;
+ bool result = strstr(name, "clang") != NULL;
free(name);
- return is;
+ return result;
}
static bool
compiler_is_gcc(struct args *args)
{
char *name = basename(args->argv[0]);
- bool is = strstr(name, "gcc") || strstr(name, "g++");
+ bool result = strstr(name, "gcc") || strstr(name, "g++");
free(name);
- return is;
+ return result;
}
// Update a hash sum with information common for the direct and preprocessor
static void
calculate_common_hash(struct args *args, struct mdfour *hash)
{
- struct stat st;
- char *p;
- const char *full_path;
-#ifdef _WIN32
- const char *ext;
- char full_path_win_ext[MAX_PATH + 1] = {0};
-#endif
-
hash_string(hash, HASH_PREFIX);
// We have to hash the extension, as a .i file isn't treated the same by the
hash_string(hash, conf->cpp_extension);
#ifdef _WIN32
- ext = strrchr(args->argv[0], '.');
+ const char *ext = strrchr(args->argv[0], '.');
+ char full_path_win_ext[MAX_PATH + 1] = {0};
add_exe_ext_if_no_to_fullpath(full_path_win_ext, MAX_PATH, ext,
args->argv[0]);
- full_path = full_path_win_ext;
+ const char *full_path = full_path_win_ext;
#else
- full_path = args->argv[0];
+ const char *full_path = args->argv[0];
#endif
+ struct stat st;
if (x_stat(full_path, &st) != 0) {
stats_update(STATS_COMPILER);
failed();
// Also hash the compiler name as some compilers use hard links and behave
// differently depending on the real name.
hash_delimiter(hash, "cc_name");
- p = basename(args->argv[0]);
+ char *p = basename(args->argv[0]);
hash_string(hash, p);
free(p);
char *map = debug_prefix_map;
char *sep = strchr(map, '=');
if (sep) {
- char *dir, *old, *new;
- old = x_strndup(map, sep - map);
- new = x_strdup(sep + 1);
+ char *old = x_strndup(map, sep - map);
+ char *new = x_strdup(sep + 1);
cc_log("Relocating debuginfo cwd %s, from %s to %s", cwd, old, new);
if (str_startswith(cwd, old)) {
- dir = format("%s%s", new, cwd + strlen(old));
+ char *dir = format("%s%s", new, cwd + strlen(old));
free(cwd);
cwd = dir;
}
dir = real_dir;
}
if (dir) {
- char *gcda_path;
char *base_name = basename(output_obj);
p = remove_extension(base_name);
free(base_name);
- gcda_path = format("%s/%s.gcda", dir, p);
+ char *gcda_path = format("%s/%s.gcda", dir, p);
cc_log("Hashing coverage path %s", gcda_path);
free(p);
hash_delimiter(hash, "gcda");
}
if (!str_eq(conf->extra_files_to_hash, "")) {
- char *path, *p, *q, *saveptr = NULL;
- p = x_strdup(conf->extra_files_to_hash);
- q = p;
+ char *p = x_strdup(conf->extra_files_to_hash);
+ char *q = p;
+ char *path;
+ char *saveptr = NULL;
while ((path = strtok_r(q, PATH_DELIM, &saveptr))) {
cc_log("Hashing extra file %s", path);
hash_delimiter(hash, "extrafile");
static struct file_hash *
calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
{
- int i;
- struct stat st;
- struct file_hash *object_hash = NULL;
- char *p;
-
if (direct_mode) {
hash_delimiter(hash, "manifest version");
hash_int(hash, MANIFEST_VERSION);
}
// First the arguments.
- for (i = 1; i < args->argc; i++) {
+ for (int i = 1; i < args->argc; i++) {
// -L doesn't affect compilation.
if (i < args->argc-1 && str_eq(args->argv[i], "-L")) {
i++;
continue;
}
} else if (str_startswith(args->argv[i], "-MF")) {
- bool separate_argument = (strlen(args->argv[i]) == 3);
-
// In either case, hash the "-MF" part.
hash_string_length(hash, args->argv[i], 3);
+ bool separate_argument = (strlen(args->argv[i]) == 3);
if (separate_argument) {
// Next argument is dependency name, so skip it.
i++;
}
}
- p = NULL;
+ char *p = NULL;
if (str_startswith(args->argv[i], "-specs=")) {
p = args->argv[i] + 7;
} else if (str_startswith(args->argv[i], "--specs=")) {
p = args->argv[i] + 8;
}
+
+ struct stat st;
if (p && x_stat(p, &st) == 0) {
// If given an explicit specs file, then hash that file, but don't
// include the path to it in the hash.
if (profile_use) {
// Calculate gcda name.
- char *gcda_name;
- char *base_name;
- base_name = remove_extension(output_obj);
if (!profile_dir) {
profile_dir = get_cwd();
}
- gcda_name = format("%s/%s.gcda", profile_dir, base_name);
+ char *base_name = remove_extension(output_obj);
+ char *gcda_name = format("%s/%s.gcda", profile_dir, base_name);
cc_log("Adding profile data %s to our hash", gcda_name);
// Add the gcda to our hash.
hash_delimiter(hash, "-fprofile-use");
free(gcda_name);
}
+ struct file_hash *object_hash = NULL;
if (direct_mode) {
- char *manifest_name;
- int result;
-
// Hash environment variables that affect the preprocessor output.
- const char **p;
const char *envvars[] = {
"CPATH",
"C_INCLUDE_PATH",
"OBJCPLUS_INCLUDE_PATH", // clang
NULL
};
- for (p = envvars; *p; ++p) {
+ for (const char **p = envvars; *p; ++p) {
char *v = getenv(*p);
if (v) {
hash_delimiter(hash, *p);
}
hash_delimiter(hash, "sourcecode");
- result = hash_source_code_file(conf, hash, input_file);
+ int result = hash_source_code_file(conf, hash, input_file);
if (result & HASH_SOURCE_CODE_ERROR) {
failed();
}
conf->direct_mode = false;
return NULL;
}
- manifest_name = hash_result(hash);
+ char *manifest_name = hash_result(hash);
manifest_path = get_path_in_cache(manifest_name, ".manifest");
free(manifest_name);
cc_log("Looking for object file hash in %s", manifest_path);
object_hash = get_object_name_from_cpp(args, hash);
cc_log("Got object file hash from preprocessor");
} else {
- size_t i;
args_add(args, "-arch");
- for (i = 0; i < arch_args_size; ++i) {
+ for (size_t i = 0; i < arch_args_size; ++i) {
args_add(args, arch_args[i]);
object_hash = get_object_name_from_cpp(args, hash);
cc_log("Got object file hash from preprocessor with -arch %s",
static void
from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
{
- struct stat st;
- bool produce_dep_file = false;
-
// The user might be disabling cache hits.
if (conf->recache) {
return;
}
+ struct stat st;
if (stat(cached_obj, &st) != 0) {
cc_log("Object file %s not in cache", cached_obj);
return;
}
// (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by gcc.)
- produce_dep_file = generating_dependencies && mode == FROMCACHE_DIRECT_MODE;
+ bool produce_dep_file =
+ generating_dependencies && mode == FROMCACHE_DIRECT_MODE;
// If the dependency file should be in the cache, check that it is.
if (produce_dep_file && stat(cached_dep, &st) != 0) {
static void
find_compiler(char **argv)
{
- char *base;
- char *compiler;
-
- base = basename(argv[0]);
-
// We might be being invoked like "ccache gcc -c foo.c".
+ char *base = basename(argv[0]);
if (same_executable_name(base, MYNAME)) {
args_remove_first(orig_args);
free(base);
base = conf->compiler;
}
- compiler = find_executable(base, MYNAME);
-
- // Can't find the compiler!
+ char *compiler = find_executable(base, MYNAME);
if (!compiler) {
stats_update(STATS_COMPILER);
fatal("Could not find compiler \"%s\" in PATH", base);
static bool
detect_pch(const char *option, const char *arg, bool *found_pch)
{
- char *pch_file = NULL;
struct stat st;
// Try to be smart about detecting precompiled headers.
+ char *pch_file = NULL;
if (str_eq(option, "-include-pch") || str_eq(option, "-include-pth")) {
if (stat(arg, &st) == 0) {
cc_log("Detected use of precompiled header: %s", arg);
cc_process_args(struct args *args, struct args **preprocessor_args,
struct args **compiler_args)
{
- int i;
- size_t j;
bool found_c_opt = false;
bool found_S_opt = false;
bool found_pch = false;
const char *file_language; // As deduced from file extension.
const char *actual_language; // Language to actually use.
const char *input_charset = NULL;
- struct stat st;
// Is the dependency makefile name overridden with -MF?
bool dependency_filename_specified = false;
// Is the dependency makefile target name specified with -MT or -MQ?
// expanded_args is a copy of the original arguments given to the compiler
// but with arguments from @file and similar constructs expanded. It's only
// used as a temporary data structure to loop over.
- struct args *expanded_args;
+ struct args *expanded_args = args_copy(args);
// stripped_args essentially contains all original arguments except those
// that only should be passed to the preprocessor (if run_second_cpp is
// false) and except dependency options (like -MD and friends).
- struct args *stripped_args;
+ struct args *stripped_args = args_init(0, NULL);
// cpp_args contains arguments that were not added to stripped_args, i.e.
// those that should only be passed to the preprocessor if run_second_cpp is
// false. If run_second_cpp is true, they will be passed to the compiler as
// well.
- struct args *cpp_args;
+ struct args *cpp_args = args_init(0, NULL);
// dep_args contains dependency options like -MD. They only passed to the
// preprocessor, never to the compiler.
- struct args *dep_args;
- int argc;
- char **argv;
- bool result = true;
+ struct args *dep_args = args_init(0, NULL);
+
bool found_color_diagnostics = false;
int debug_level = 0;
const char *debug_argument = NULL;
- expanded_args = args_copy(args);
- stripped_args = args_init(0, NULL);
- dep_args = args_init(0, NULL);
- cpp_args = args_init(0, NULL);
-
- argc = expanded_args->argc;
- argv = expanded_args->argv;
-
+ int argc = expanded_args->argc;
+ char **argv = expanded_args->argv;
args_add(stripped_args, argv[0]);
- for (i = 1; i < argc; i++) {
+ bool result = true;
+ for (int i = 1; i < argc; i++) {
// The user knows best: just swallow the next arg.
if (str_eq(argv[i], "--ccache-skip")) {
i++;
// Handle "@file" argument.
if (str_startswith(argv[i], "@") || str_startswith(argv[i], "-@")) {
char *argpath = argv[i] + 1;
- struct args *file_args;
if (argpath[-1] == '-') {
++argpath;
}
- file_args = args_init_from_gcc_atfile(argpath);
+ struct args *file_args = args_init_from_gcc_atfile(argpath);
if (!file_args) {
cc_log("Couldn't read arg file %s", argpath);
stats_update(STATS_ARGS);
}
// These are always too hard.
- if (compopt_too_hard(argv[i])
- || str_startswith(argv[i], "-fdump-")) {
+ if (compopt_too_hard(argv[i]) || str_startswith(argv[i], "-fdump-")) {
cc_log("Compiler option %s is unsupported", argv[i]);
stats_update(STATS_UNSUPPORTED);
result = false;
}
// These are too hard in direct mode.
- if (conf->direct_mode) {
- if (compopt_too_hard_for_direct_mode(argv[i])) {
- cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
- conf->direct_mode = false;
- }
+ if (conf->direct_mode && compopt_too_hard_for_direct_mode(argv[i])) {
+ cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
+ conf->direct_mode = false;
}
// -Xarch_* options are too hard.
// number info.
if (str_startswith(argv[i], "-g")) {
const char *pLevel = argv[i] + 2;
- int foundlevel = -1;
if (str_startswith(argv[i], "-ggdb")) {
pLevel = argv[i] + 5;
} else if (str_startswith(argv[i], "-gstabs")) {
}
// Deduce level from argument, default is 2.
+ int foundlevel = -1;
if (pLevel[0] == '\0') {
foundlevel = 2;
} else if (pLevel[0] >= '0' && pLevel[0] <= '9') {
continue;
}
if (str_startswith(argv[i], "-MF")) {
- char *arg;
- bool separate_argument = (strlen(argv[i]) == 3);
dependency_filename_specified = true;
free(output_dep);
+
+ char *arg;
+ bool separate_argument = (strlen(argv[i]) == 3);
if (separate_argument) {
// -MF arg
if (i >= argc - 1) {
continue;
}
if (str_startswith(argv[i], "-MQ") || str_startswith(argv[i], "-MT")) {
- char *relpath;
dependency_target_specified = true;
+
+ char *relpath;
if (strlen(argv[i]) == 3) {
// -MQ arg or -MT arg
if (i >= argc - 1) {
free(relpath);
i++;
} else {
- char *arg_opt;
- char *option;
- arg_opt = x_strndup(argv[i], 3);
+ char *arg_opt = x_strndup(argv[i], 3);
relpath = make_relative_path(x_strdup(argv[i] + 3));
- option = format("%s%s", arg_opt, relpath);
+ char *option = format("%s%s", arg_opt, relpath);
args_add(dep_args, option);
free(arg_opt);
free(relpath);
}
if (str_startswith(argv[i], "-fprofile-")) {
- const char *arg_profile_dir = strchr(argv[i], '=');
char *arg = x_strdup(argv[i]);
- bool supported_profile_option = false;
-
+ const char *arg_profile_dir = strchr(argv[i], '=');
if (arg_profile_dir) {
- char *option = x_strndup(argv[i], arg_profile_dir - argv[i]);
- char *dir;
-
// Convert to absolute path.
- dir = x_realpath(arg_profile_dir + 1);
+ char *dir = x_realpath(arg_profile_dir + 1);
if (!dir) {
// Directory doesn't exist.
dir = x_strdup(arg_profile_dir + 1);
// We can get a better hit rate by using the real path here.
free(arg);
+ char *option = x_strndup(argv[i], arg_profile_dir - argv[i]);
arg = format("%s=%s", option, dir);
cc_log("Rewriting %s to %s", argv[i], arg);
free(option);
free(dir);
}
+ bool supported_profile_option = false;
if (str_startswith(argv[i], "-fprofile-generate")
|| str_eq(argv[i], "-fprofile-arcs")) {
profile_generate = true;
// to get better hit rate. A secondary effect is that paths in the standard
// error output produced by the compiler will be normalized.
if (compopt_takes_path(argv[i])) {
- char *relpath;
if (i == argc-1) {
cc_log("Missing argument to %s", argv[i]);
stats_update(STATS_ARGS);
goto out;
}
- relpath = make_relative_path(x_strdup(argv[i+1]));
+ char *relpath = make_relative_path(x_strdup(argv[i+1]));
if (compopt_affects_cpp(argv[i])) {
args_add(cpp_args, argv[i]);
args_add(cpp_args, relpath);
// If an argument isn't a plain file then assume its an option, not an
// input file. This allows us to cope better with unusual compiler options.
+ struct stat st;
if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
cc_log("%s is not a regular file, not considering as input file",
argv[i]);
if (output_is_precompiled_header) {
output_obj = format("%s.gch", input_file);
} else {
- char *p;
output_obj = basename(input_file);
- p = strrchr(output_obj, '.');
+ char *p = strrchr(output_obj, '.');
if (!p || !p[1]) {
cc_log("Badly formed object filename");
stats_update(STATS_ARGS);
}
if (using_split_dwarf) {
- char *p;
- p = strrchr(output_obj, '.');
+ char *p = strrchr(output_obj, '.');
if (!p || !p[1]) {
cc_log("Badly formed object filename");
stats_update(STATS_ARGS);
result = false;
goto out;
}
- {
- char *base_name = remove_extension(output_obj);
- output_dwo = format("%s.dwo", base_name);
- free(base_name);
- }
+
+ char *base_name = remove_extension(output_obj);
+ output_dwo = format("%s.dwo", base_name);
+ free(base_name);
}
// Cope with -o /dev/null.
+ struct stat st;
if (!str_eq(output_obj, "/dev/null")
&& stat(output_obj, &st) == 0
&& !S_ISREG(st.st_mode)) {
// Add flags for dependency generation only to the preprocessor command line.
if (generating_dependencies) {
if (!dependency_filename_specified) {
- char *default_depfile_name;
- char *base_name;
-
- base_name = remove_extension(output_obj);
- default_depfile_name = format("%s.d", base_name);
+ char *base_name = remove_extension(output_obj);
+ char *default_depfile_name = format("%s.d", base_name);
free(base_name);
args_add(dep_args, "-MF");
args_add(dep_args, default_depfile_name);
}
}
if (generating_coverage) {
- char *default_covfile_name;
- char *base_name;
-
- base_name = remove_extension(output_obj);
- default_covfile_name = format("%s.gcno", base_name);
+ char *base_name = remove_extension(output_obj);
+ char *default_covfile_name = format("%s.gcno", base_name);
free(base_name);
output_cov = make_relative_path(x_strdup(default_covfile_name));
}
*compiler_args = args_copy(stripped_args);
if (conf->run_second_cpp) {
args_extend(*compiler_args, cpp_args);
- } else {
- if (explicit_language) {
- // Workaround for a bug in Apple's patched distcc -- it doesn't properly
- // reset the language specified with -x, so if -x is given, we have to
- // specify the preprocessed language explicitly.
- args_add(*compiler_args, "-x");
- args_add(*compiler_args, p_language_for_language(explicit_language));
- }
+ } else if (explicit_language) {
+ // Workaround for a bug in Apple's patched distcc -- it doesn't properly
+ // reset the language specified with -x, so if -x is given, we have to
+ // specify the preprocessed language explicitly.
+ args_add(*compiler_args, "-x");
+ args_add(*compiler_args, p_language_for_language(explicit_language));
}
if (found_c_opt) {
args_add(*compiler_args, "-c");
}
- for (j = 0; j < arch_args_size; ++j) {
+ for (size_t i = 0; i < arch_args_size; ++i) {
args_add(*compiler_args, "-arch");
- args_add(*compiler_args, arch_args[j]);
+ args_add(*compiler_args, arch_args[i]);
}
// Only pass dependency arguments to the preprocesor since Intel's C++
static void
create_initial_config_file(struct conf *conf, const char *path)
{
- unsigned max_files;
- uint64_t max_size;
- char *stats_dir;
- FILE *f;
- struct stat st;
-
if (create_parent_dirs(path) != 0) {
return;
}
- stats_dir = format("%s/0", conf->cache_dir);
+ unsigned max_files;
+ uint64_t max_size;
+ char *stats_dir = format("%s/0", conf->cache_dir);
+ struct stat st;
if (stat(stats_dir, &st) == 0) {
stats_get_obsolete_limits(stats_dir, &max_files, &max_size);
// STATS_MAXFILES and STATS_MAXSIZE was stored for each top directory.
}
free(stats_dir);
- f = fopen(path, "w");
+ FILE *f = fopen(path, "w");
if (!f) {
return;
}
static void
initialize(void)
{
- char *errmsg;
- char *p;
- struct stat st;
- bool should_create_initial_config = false;
-
conf_free(conf);
conf = conf_create();
- p = getenv("CCACHE_CONFIGPATH");
+ char *errmsg;
+ struct stat st;
+ char *p = getenv("CCACHE_CONFIGPATH");
if (p) {
primary_config_path = x_strdup(p);
} else {
primary_config_path = format("%s/ccache.conf", conf->cache_dir);
}
+ bool should_create_initial_config = false;
if (!conf_read(conf, primary_config_path, &errmsg)) {
if (stat(primary_config_path, &st) == 0) {
fatal("%s", errmsg);
void
cc_reset(void)
{
- size_t i;
-
conf_free(conf); conf = NULL;
free(primary_config_path); primary_config_path = NULL;
free(secondary_config_path); secondary_config_path = NULL;
free(cached_dia); cached_dia = NULL;
free(manifest_path); manifest_path = NULL;
time_of_compilation = 0;
- for (i = 0; i < ignore_headers_len; i++) {
+ for (size_t i = 0; i < ignore_headers_len; i++) {
free(ignore_headers[i]);
ignore_headers[i] = NULL;
}
static void
setup_uncached_err(void)
{
- char *buf;
- int uncached_fd;
-
- uncached_fd = dup(2);
+ int uncached_fd = dup(2);
if (uncached_fd == -1) {
cc_log("dup(2) failed: %s", strerror(errno));
failed();
}
// Leak a pointer to the environment.
- buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
-
+ char *buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
if (putenv(buf) == -1) {
cc_log("putenv failed: %s", strerror(errno));
failed();
static void
ccache(int argc, char *argv[])
{
- bool put_object_in_manifest = false;
- struct file_hash *object_hash;
- struct file_hash *object_hash_from_manifest = NULL;
- struct mdfour common_hash;
- struct mdfour direct_hash;
- struct mdfour cpp_hash;
-
- // Arguments (except -E) to send to the preprocessor.
- struct args *preprocessor_args;
-
- // Arguments to send to the real compiler.
- struct args *compiler_args;
-
#ifndef _WIN32
set_up_signal_handlers();
#endif
conf->direct_mode = false;
}
+ // Arguments (except -E) to send to the preprocessor.
+ struct args *preprocessor_args;
+ // Arguments to send to the real compiler.
+ struct args *compiler_args;
if (!cc_process_args(orig_args, &preprocessor_args, &compiler_args)) {
failed();
}
cc_log("Object file: %s", output_obj);
+ struct mdfour common_hash;
hash_start(&common_hash);
calculate_common_hash(preprocessor_args, &common_hash);
// Try to find the hash using the manifest.
- direct_hash = common_hash;
+ struct mdfour direct_hash = common_hash;
+ bool put_object_in_manifest = false;
+ struct file_hash *object_hash = NULL;
+ struct file_hash *object_hash_from_manifest = NULL;
if (conf->direct_mode) {
cc_log("Trying direct lookup");
object_hash = calculate_object_hash(preprocessor_args, &direct_hash, 1);
}
// Find the hash using the preprocessed output. Also updates included_files.
- cpp_hash = common_hash;
+ struct mdfour cpp_hash = common_hash;
object_hash = calculate_object_hash(preprocessor_args, &cpp_hash, 0);
if (!object_hash) {
fatal("internal error: object hash from cpp returned NULL");
static int
ccache_main_options(int argc, char *argv[])
{
- int c;
- char *errmsg;
-
enum longopts {
DUMP_MANIFEST
};
{0, 0, 0, 0}
};
+ int c;
while ((c = getopt_long(argc, argv, "cChF:M:o:psVz", options, NULL)) != -1) {
switch (c) {
case DUMP_MANIFEST:
case 'F': // --max-files
{
- unsigned files;
initialize();
- files = atoi(optarg);
+ char *errmsg;
if (conf_set_value_in_file(primary_config_path, "max_files", optarg,
&errmsg)) {
+ unsigned files = atoi(optarg);
if (files == 0) {
printf("Unset cache file limit\n");
} else {
case 'M': // --max-size
{
- uint64_t size;
initialize();
+ uint64_t size;
if (!parse_size_with_suffix(optarg, &size)) {
fatal("invalid size: %s", optarg);
}
+ char *errmsg;
if (conf_set_value_in_file(primary_config_path, "max_size", optarg,
&errmsg)) {
if (size == 0) {
case 'o': // --set-config
{
- char *errmsg, *key, *value, *p;
initialize();
- p = strchr(optarg, '=');
+ char *p = strchr(optarg, '=');
if (!p) {
fatal("missing equal sign in \"%s\"", optarg);
}
- key = x_strndup(optarg, p - optarg);
- value = p + 1;
+ char *key = x_strndup(optarg, p - optarg);
+ char *value = p + 1;
+ char *errmsg;
if (!conf_set_value_in_file(primary_config_path, key, value, &errmsg)) {
fatal("%s", errmsg);
}
static void
traverse_fn(const char *fname, struct stat *st)
{
- char *p;
-
if (!S_ISREG(st->st_mode)) {
return;
}
- p = basename(fname);
+ char *p = basename(fname);
if (str_eq(p, "stats")) {
goto out;
}
goto out;
}
- if (strstr(p, ".tmp.")) {
- // Delete any tmp files older than 1 hour.
- if (st->st_mtime + 3600 < time(NULL)) {
- x_unlink(fname);
- goto out;
- }
+ // Delete any tmp files older than 1 hour.
+ if (strstr(p, ".tmp.") && st->st_mtime + 3600 < time(NULL)) {
+ x_unlink(fname);
+ goto out;
}
if (strstr(p, "CACHEDIR.TAG")) {
delete_sibling_file(const char *base, const char *extension)
{
struct stat st;
- char *path;
-
- path = format("%s%s", base, extension);
+ char *path = format("%s%s", base, extension);
if (lstat(path, &st) == 0) {
delete_file(path, file_size(&st));
} else if (errno != ENOENT && errno != ESTALE) {
static bool
sort_and_clean(void)
{
- unsigned i;
- char *last_base = x_strdup("");
- bool cleaned = false;
-
if (num_files > 1) {
// Sort in ascending mtime order.
qsort(files, num_files, sizeof(struct files *), (COMPAR_FN_T)files_compare);
}
// Delete enough files to bring us below the threshold.
- for (i = 0; i < num_files; i++) {
+ char *last_base = x_strdup("");
+ bool cleaned = false;
+ for (unsigned i = 0; i < num_files; i++) {
const char *ext;
if ((cache_size_threshold == 0
void
cleanup_dir(struct conf *conf, const char *dir)
{
- unsigned i;
- bool cleaned;
-
cc_log("Cleaning up cache directory %s", dir);
cache_size_threshold = conf->max_size * LIMIT_MULTIPLE / 16;
traverse(dir, traverse_fn);
// Clean the cache.
- cleaned = sort_and_clean();
-
+ bool cleaned = sort_and_clean();
if (cleaned) {
cc_log("Cleaned up cache directory %s", dir);
stats_add_cleanup(dir, 1);
stats_set_sizes(dir, files_in_cache, cache_size);
// Free it up.
- for (i = 0; i < num_files; i++) {
+ for (unsigned i = 0; i < num_files; i++) {
free(files[i]->fname);
free(files[i]);
files[i] = NULL;
// Clean up all cache subdirectories.
void cleanup_all(struct conf *conf)
{
- int i;
-
- for (i = 0; i <= 0xF; i++) {
+ for (int i = 0; i <= 0xF; i++) {
char *dname = format("%s/%1x", conf->cache_dir, i);
cleanup_dir(conf, dname);
free(dname);
// Traverse function for wiping files.
static void wipe_fn(const char *fname, struct stat *st)
{
- char *p;
-
if (!S_ISREG(st->st_mode)) {
return;
}
- p = basename(fname);
+ char *p = basename(fname);
if (str_eq(p, "stats")) {
free(p);
return;
cc_log("Clearing out cache directory %s", dir);
files_in_cache_threshold = conf->max_files * LIMIT_MULTIPLE / 16;
-
files_in_cache = 0;
traverse(dir, wipe_fn);
// Wipe all cached files in all subdirectories.
void wipe_all(struct conf *conf)
{
- int i;
-
- for (i = 0; i <= 0xF; i++) {
+ for (int i = 0; i <= 0xF; i++) {
char *dname = format("%s/%1x", conf->cache_dir, i);
wipe_dir(conf, dname);
free(dname);
bool
compopt_verify_sortedness(void)
{
- size_t i;
- for (i = 1; i < sizeof(compopts)/sizeof(compopts[0]); i++) {
+ for (size_t i = 1; i < sizeof(compopts)/sizeof(compopts[0]); i++) {
if (strcmp(compopts[i-1].name, compopts[i].name) >= 0) {
fprintf(stderr,
"compopt_verify_sortedness: %s >= %s\n",
{
uint64_t *value = (uint64_t *)result;
uint64_t size;
- *errmsg = NULL;
if (parse_size_with_suffix(str, &size)) {
*value = size;
return true;
parse_sloppiness(const char *str, void *result, char **errmsg)
{
unsigned *value = (unsigned *)result;
- char *word, *p, *q, *saveptr = NULL;
-
if (!str) {
return *value;
}
- p = x_strdup(str);
- q = p;
+
+ char *p = x_strdup(str);
+ char *q = p;
+ char *word;
+ char *saveptr = NULL;
while ((word = strtok_r(q, ", ", &saveptr))) {
if (str_eq(word, "file_macro")) {
*value |= SLOPPY_FILE_MACRO;
static bool
parse_string(const char *str, void *result, char **errmsg)
{
- char **value = (char **)result;
(void)errmsg;
+
+ char **value = (char **)result;
free(*value);
*value = x_strdup(str);
return true;
parse_umask(const char *str, void *result, char **errmsg)
{
unsigned *value = (unsigned *)result;
- char *endptr;
if (str_eq(str, "")) {
*value = UINT_MAX;
return true;
}
+
errno = 0;
+ char *endptr;
*value = strtoul(str, &endptr, 8);
if (errno == 0 && *str != '\0' && *endptr == '\0') {
return true;
parse_unsigned(const char *str, void *result, char **errmsg)
{
unsigned *value = (unsigned *)result;
- long x;
- char *endptr;
errno = 0;
- x = strtol(str, &endptr, 10);
+ char *endptr;
+ long x = strtol(str, &endptr, 10);
if (errno == 0 && x >= 0 && *str != '\0' && *endptr == '\0') {
*value = x;
return true;
char **errmsg, bool from_env_variable, bool negate_boolean,
const char *origin)
{
- const struct conf_item *item;
-
- item = find_conf(key);
+ const struct conf_item *item = find_conf(key);
if (!item) {
*errmsg = format("unknown configuration option \"%s\"", key);
return false;
static bool
parse_line(const char *line, char **key, char **value, char **errmsg)
{
- const char *p, *q;
-
#define SKIP_WS(x) while (isspace(*x)) { ++x; }
*key = NULL;
*value = NULL;
- p = line;
+ const char *p = line;
SKIP_WS(p);
if (*p == '\0' || *p == '#') {
return true;
}
- q = p;
+ const char *q = p;
while (isalpha(*q) || *q == '_') {
++q;
}
struct conf *
conf_create(void)
{
- size_t i;
struct conf *conf = x_malloc(sizeof(*conf));
conf->base_dir = x_strdup("");
conf->cache_dir = format("%s/.ccache", get_home_directory());
conf->umask = UINT_MAX; // Default: don't set umask.
conf->unify = false;
conf->item_origins = x_malloc(CONFITEMS_TOTAL_KEYWORDS * sizeof(char *));
- for (i = 0; i < CONFITEMS_TOTAL_KEYWORDS; ++i) {
+ for (size_t i = 0; i < CONFITEMS_TOTAL_KEYWORDS; ++i) {
conf->item_origins[i] = "default";
}
return conf;
bool
conf_read(struct conf *conf, const char *path, char **errmsg)
{
- FILE *f;
- char buf[10000];
- bool result = true;
- unsigned line_number;
-
assert(errmsg);
*errmsg = NULL;
- f = fopen(path, "r");
+ FILE *f = fopen(path, "r");
if (!f) {
*errmsg = format("%s: %s", path, strerror(errno));
return false;
}
- line_number = 0;
+ unsigned line_number = 0;
+ bool result = true;
+ char buf[10000];
while (fgets(buf, sizeof(buf), f)) {
- char *errmsg2, *key, *value;
- bool ok;
++line_number;
- ok = parse_line(buf, &key, &value, &errmsg2);
+
+ char *key;
+ char *value;
+ char *errmsg2;
+ bool ok = parse_line(buf, &key, &value, &errmsg2);
if (ok && key) { // key == NULL if comment or blank line.
ok = handle_conf_setting(conf, key, value, &errmsg2, false, false, path);
}
bool
conf_update_from_environment(struct conf *conf, char **errmsg)
{
- char **p;
- char *q;
- char *key;
- char *errmsg2;
- const struct env_to_conf_item *env_to_conf_item;
- bool negate;
- size_t key_start;
-
- for (p = environ; *p; ++p) {
+ for (char **p = environ; *p; ++p) {
if (!str_startswith(*p, "CCACHE_")) {
continue;
}
- q = strchr(*p, '=');
+ char *q = strchr(*p, '=');
if (!q) {
continue;
}
+ bool negate;
+ size_t key_start;
if (str_startswith(*p + 7, "NO")) {
negate = true;
key_start = 9;
negate = false;
key_start = 7;
}
- key = x_strndup(*p + key_start, q - *p - key_start);
+ char *key = x_strndup(*p + key_start, q - *p - key_start);
++q; // Now points to the value.
- env_to_conf_item = find_env_to_conf(key);
+ const struct env_to_conf_item *env_to_conf_item = find_env_to_conf(key);
if (!env_to_conf_item) {
free(key);
continue;
}
+ char *errmsg2;
if (!handle_conf_setting(
conf, env_to_conf_item->conf_name, q, &errmsg2, true, negate,
"environment")) {
conf_set_value_in_file(const char *path, const char *key, const char *value,
char **errmsg)
{
- FILE *infile, *outfile;
- char *outpath;
- char buf[10000];
- bool found;
- const struct conf_item *item;
-
- item = find_conf(key);
+ const struct conf_item *item = find_conf(key);
if (!item) {
*errmsg = format("unknown configuration option \"%s\"", key);
return false;
}
- infile = fopen(path, "r");
+ FILE *infile = fopen(path, "r");
if (!infile) {
*errmsg = format("%s: %s", path, strerror(errno));
return false;
}
- outpath = format("%s.tmp", path);
- outfile = create_tmp_file(&outpath, "w");
+ char *outpath = format("%s.tmp", path);
+ FILE *outfile = create_tmp_file(&outpath, "w");
if (!outfile) {
*errmsg = format("%s: %s", outpath, strerror(errno));
free(outpath);
return false;
}
- found = false;
+ bool found = false;
+ char buf[10000];
while (fgets(buf, sizeof(buf), infile)) {
- char *errmsg2, *key2, *value2;
- bool ok;
- ok = parse_line(buf, &key2, &value2, &errmsg2);
+ char *key2;
+ char *value2;
+ char *errmsg2;
+ bool ok = parse_line(buf, &key2, &value2, &errmsg2);
if (ok && key2 && str_eq(key2, key)) {
found = true;
fprintf(outfile, "%s = %s\n", key, value);
void *context)
{
char *s = x_strdup("");
- char *s2;
reformat(&s, "base_dir = %s", conf->base_dir);
printer(s, conf->item_origins[find_conf("base_dir")->number], context);
reformat(&s, "max_files = %u", conf->max_files);
printer(s, conf->item_origins[find_conf("max_files")->number], context);
- s2 = format_parsable_size_with_suffix(conf->max_size);
+ char *s2 = format_parsable_size_with_suffix(conf->max_size);
reformat(&s, "max_size = %s", s2);
printer(s, conf->item_origins[find_conf("max_size")->number], context);
free(s2);
counters_resize(struct counters *c, size_t new_size)
{
if (new_size > c->size) {
- size_t i;
bool realloc = false;
-
while (c->allocated < new_size) {
c->allocated += 32 + c->allocated;
realloc = true;
if (realloc) {
c->data = x_realloc(c->data, c->allocated * sizeof(c->data[0]));
}
- for (i = c->size; i < new_size; i++) {
+ for (size_t i = c->size; i < new_size; i++) {
c->data[i] = 0;
}
}
char *
win32argvtos(char *prefix, char **argv)
{
- char *arg;
- char *ptr;
- char *str;
- int l = 0;
- int i, j;
-
- i = 0;
- arg = prefix ? prefix : argv[i++];
+ int i = 0;
+ int k = 0;
+ char *arg = prefix ? prefix : argv[i++];
do {
int bs = 0;
- for (j = 0; arg[j]; j++) {
+ for (int j = 0; arg[j]; j++) {
switch (arg[j]) {
case '\\':
bs++;
case '"':
bs = (bs << 1) + 1;
default:
- l += bs + 1;
+ k += bs + 1;
bs = 0;
}
}
- l += (bs << 1) + 3;
+ k += (bs << 1) + 3;
} while ((arg = argv[i++]));
- str = ptr = malloc(l + 1);
+ char *ptr = malloc(k + 1);
+ char *str = ptr;
if (!str) {
return NULL;
}
{
char *path_env;
char *sh = NULL;
- const char *ext;
-
- ext = get_extension(path);
+ const char *ext = get_extension(path);
if (ext && strcasecmp(ext, ".sh") == 0 && (path_env = getenv("PATH"))) {
sh = find_executable_in_path("sh.exe", NULL, path_env);
}
if (!sh && getenv("CCACHE_DETECT_SHEBANG")) {
// Detect shebang.
- FILE *fp;
- fp = fopen(path, "r");
+ FILE *fp = fopen(path, "r");
if (fp) {
char buf[10];
fgets(buf, sizeof(buf), fp);
int fd_stdout, int fd_stderr)
{
PROCESS_INFORMATION pi;
- STARTUPINFO si;
- BOOL ret;
- DWORD exitcode;
- char *sh = NULL;
- char *args;
-
memset(&pi, 0x00, sizeof(pi));
+
+ STARTUPINFO si;
memset(&si, 0x00, sizeof(si));
- sh = win32getshell(path);
+ char *sh = win32getshell(path);
if (sh) {
path = sh;
}
return -1;
}
}
- args = win32argvtos(sh, argv);
+ char *args = win32argvtos(sh, argv);
const char *ext = strrchr(path, '.');
char full_path_win_ext[MAX_PATH] = {0};
add_exe_ext_if_no_to_fullpath(full_path_win_ext, MAX_PATH, ext, path);
- ret = CreateProcess(full_path_win_ext, args, NULL, NULL, 1, 0, NULL, NULL,
- &si, &pi);
+ BOOL ret =
+ CreateProcess(full_path_win_ext, args, NULL, NULL, 1, 0, NULL, NULL,
+ &si, &pi);
if (fd_stdout != -1) {
close(fd_stdout);
close(fd_stderr);
free(args);
if (ret == 0) {
LPVOID lpMsgBuf;
- LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
-
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
0, NULL);
- lpDisplayBuf =
+ LPVOID lpDisplayBuf =
(LPVOID) LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR) lpMsgBuf)
+ lstrlen((LPCTSTR) __FILE__) + 200)
return -1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
+
+ DWORD exitcode;
GetExitCodeProcess(pi.hProcess, &exitcode);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
int
execute(char **argv, int fd_out, int fd_err, pid_t *pid)
{
- int status;
-
cc_log_argv("Executing ", argv);
block_signals();
close(fd_out);
close(fd_err);
+ int status;
if (waitpid(*pid, &status, 0) != *pid) {
fatal("waitpid failed: %s", strerror(errno));
}
char *
find_executable(const char *name, const char *exclude_name)
{
- char *path;
-
if (is_absolute_path(name)) {
return x_strdup(name);
}
- path = conf->path;
+ char *path = conf->path;
if (str_eq(path, "")) {
path = getenv("PATH");
}
static char *
find_executable_in_path(const char *name, const char *exclude_name, char *path)
{
- char *tok, *saveptr = NULL;
-
path = x_strdup(path);
// Search the path looking for the first compiler of the right name that
// isn't us.
- for (tok = strtok_r(path, PATH_DELIM, &saveptr);
+ char *saveptr = NULL;
+ for (char *tok = strtok_r(path, PATH_DELIM, &saveptr);
tok;
tok = strtok_r(NULL, PATH_DELIM, &saveptr)) {
#ifdef _WIN32
char namebuf[MAX_PATH];
- int ret = SearchPath(tok, name, NULL,
- sizeof(namebuf), namebuf, NULL);
+ int ret = SearchPath(tok, name, NULL, sizeof(namebuf), namebuf, NULL);
if (!ret) {
char *exename = format("%s.exe", name);
- ret = SearchPath(tok, exename, NULL,
- sizeof(namebuf), namebuf, NULL);
+ ret = SearchPath(tok, exename, NULL, sizeof(namebuf), namebuf, NULL);
free(exename);
}
(void) exclude_name;
void
print_command(FILE *fp, char **argv)
{
- int i;
- for (i = 0; argv[i]; i++) {
+ for (int i = 0; argv[i]; i++) {
fprintf(fp, "%s%s", (i == 0) ? "" : " ", argv[i]);
}
fprintf(fp, "\n");
void
exitfn_add(void (*function)(void *), void *context)
{
- struct exit_function *p;
-
- p = x_malloc(sizeof(*p));
+ struct exit_function *p = x_malloc(sizeof(*p));
p->function = function;
p->context = context;
p->next = exit_functions;
struct exit_function *p = exit_functions;
exit_functions = NULL;
while (p) {
- struct exit_function *q;
p->function(p->context);
- q = p;
+ struct exit_function *q = p;
p = p->next;
free(q);
}
bool
hash_equal(struct mdfour *md1, struct mdfour *md2)
{
- unsigned char sum1[16], sum2[16];
+ unsigned char sum1[16];
hash_result_as_bytes(md1, sum1);
+ unsigned char sum2[16];
hash_result_as_bytes(md2, sum2);
return memcmp(sum1, sum2, sizeof(sum1)) == 0;
}
bool
hash_file(struct mdfour *md, const char *fname)
{
- int fd;
- bool ret;
-
- fd = open(fname, O_RDONLY|O_BINARY);
+ int fd = open(fname, O_RDONLY|O_BINARY);
if (fd == -1) {
cc_log("Failed to open %s: %s", fname, strerror(errno));
return false;
}
- ret = hash_fd(md, fd);
+ bool ret = hash_fd(md, fd);
close(fd);
return ret;
}
int
hash_source_code_file(struct conf *conf, struct mdfour *hash, const char *path)
{
- char *data;
- size_t size;
-
if (is_precompiled_header(path)) {
if (hash_file(hash, path)) {
return HASH_SOURCE_CODE_OK;
return HASH_SOURCE_CODE_ERROR;
}
} else {
- int result;
-
+ char *data;
+ size_t size;
if (!read_file(path, 0, &data, &size)) {
return HASH_SOURCE_CODE_ERROR;
}
- result = hash_source_code_string(conf, hash, data, size, path);
+ int result = hash_source_code_string(conf, hash, data, size, path);
free(data);
return result;
}
hash_command_output(struct mdfour *hash, const char *command,
const char *compiler)
{
-#ifdef _WIN32
- SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
- HANDLE pipe_out[2];
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- DWORD exitcode;
- bool cmd = false;
- char *sh = NULL;
- char *win32args;
- char *path;
- BOOL ret;
- bool ok;
- int fd;
-#else
- pid_t pid;
- int pipefd[2];
-#endif
-
#ifdef _WIN32
// Trim leading space.
while (isspace(*command)) {
command++;
}
+
// Add "echo" command.
+ bool cmd;
if (str_startswith(command, "echo")) {
command = format("cmd.exe /c \"%s\"", command);
cmd = true;
cmd = true;
} else {
command = x_strdup(command);
+ cmd = false;
}
#endif
+
struct args *args = args_init_from_string(command);
- int i;
- for (i = 0; i < args->argc; i++) {
+ for (int i = 0; i < args->argc; i++) {
if (str_eq(args->argv[i], "%compiler%")) {
args_set(args, i, compiler);
}
cc_log_argv("Executing compiler check command ", args->argv);
#ifdef _WIN32
+ PROCESS_INFORMATION pi;
memset(&pi, 0x00, sizeof(pi));
+ STARTUPINFO si;
memset(&si, 0x00, sizeof(si));
- path = find_executable(args->argv[0], NULL);
+ char *path = find_executable(args->argv[0], NULL);
if (!path) {
path = args->argv[0];
}
- sh = win32getshell(path);
+ char *sh = win32getshell(path);
if (sh) {
path = sh;
}
si.cb = sizeof(STARTUPINFO);
+
+ HANDLE pipe_out[2];
+ SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
CreatePipe(&pipe_out[0], &pipe_out[1], &sa, 0);
SetHandleInformation(pipe_out[0], HANDLE_FLAG_INHERIT, 0);
si.hStdOutput = pipe_out[1];
si.hStdError = pipe_out[1];
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.dwFlags = STARTF_USESTDHANDLES;
+
+ char *win32args;
if (!cmd) {
win32args = win32argvtos(sh, args->argv);
} else {
win32args = (char *)command; // quoted
}
- ret = CreateProcess(path, win32args, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
+ BOOL ret =
+ CreateProcess(path, win32args, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
CloseHandle(pipe_out[1]);
args_free(args);
free(win32args);
stats_update(STATS_COMPCHECK);
return false;
}
- fd = _open_osfhandle((intptr_t) pipe_out[0], O_BINARY);
- ok = hash_fd(hash, fd);
+ int fd = _open_osfhandle((intptr_t) pipe_out[0], O_BINARY);
+ bool ok = hash_fd(hash, fd);
if (!ok) {
cc_log("Error hashing compiler check command output: %s", strerror(errno));
stats_update(STATS_COMPCHECK);
}
WaitForSingleObject(pi.hProcess, INFINITE);
+ DWORD exitcode;
GetExitCodeProcess(pi.hProcess, &exitcode);
CloseHandle(pipe_out[0]);
CloseHandle(pi.hProcess);
}
return ok;
#else
+ int pipefd[2];
if (pipe(pipefd) == -1) {
fatal("pipe failed");
}
- pid = fork();
+
+ pid_t pid = fork();
if (pid == -1) {
fatal("fork failed");
}
return false; // Never reached.
} else {
// Parent.
- int status;
- bool ok;
args_free(args);
close(pipefd[1]);
- ok = hash_fd(hash, pipefd[0]);
+ bool ok = hash_fd(hash, pipefd[0]);
if (!ok) {
cc_log("Error hashing compiler check command output: %s", strerror(errno));
stats_update(STATS_COMPCHECK);
}
close(pipefd[0]);
+
+ int status;
if (waitpid(pid, &status, 0) != pid) {
cc_log("waitpid failed");
return false;
hash_multicommand_output(struct mdfour *hash, const char *commands,
const char *compiler)
{
- char *command_string, *command, *p, *saveptr = NULL;
+ char *command_string = x_strdup(commands);
+ char *p = command_string;
+ char *command;
+ char *saveptr = NULL;
bool ok = true;
-
- command_string = x_strdup(commands);
- p = command_string;
while ((command = strtok_r(p, ";", &saveptr))) {
if (!hash_command_output(hash, command, compiler)) {
ok = false;
{".FPP", "f77-cpp-input"},
{".FTN", "f77-cpp-input"},
// Free form Fortran without preprocessing:
-#if 0 // Could generate modules, ignore for now!
+#if 0 // Could generate modules, ignore for now!
{".f90", "f95"},
{".f95", "f95"},
{".f03", "f95"},
const char *
language_for_file(const char *fname)
{
- int i;
- const char *p;
-
- p = get_extension(fname);
- for (i = 0; extensions[i].extension; i++) {
+ const char *p = get_extension(fname);
+ for (int i = 0; extensions[i].extension; i++) {
if (str_eq(p, extensions[i].extension)) {
return extensions[i].language;
}
const char *
p_language_for_language(const char *language)
{
- int i;
-
if (!language) {
return NULL;
}
- for (i = 0; languages[i].language; ++i) {
+ for (int i = 0; languages[i].language; ++i) {
if (str_eq(language, languages[i].language)) {
return languages[i].p_language;
}
const char *
extension_for_language(const char *language)
{
- int i;
-
if (!language) {
return NULL;
}
- for (i = 0; extensions[i].extension; i++) {
+ for (int i = 0; extensions[i].extension; i++) {
if (str_eq(language, extensions[i].language)) {
return extensions[i].extension;
}
bool
lockfile_acquire(const char *path, unsigned staleness_limit)
{
- int saved_errno = 0;
char *lockfile = format("%s.lock", path);
- char *my_content = NULL, *content = NULL, *initial_content = NULL;
+ char *my_content = NULL;
+ char *content = NULL;
+ char *initial_content = NULL;
const char *hostname = get_hostname();
bool acquired = false;
-#ifdef _WIN32
- const size_t bufsize = 1024;
- int fd, len;
-#else
- int ret;
-#endif
- unsigned to_sleep = 1000, slept = 0; // Microseconds.
+ unsigned to_sleep = 1000; // Microseconds.
+ unsigned slept = 0; // Microseconds.
while (true) {
free(my_content);
my_content = format("%s:%d:%d", hostname, (int)getpid(), (int)time(NULL));
#ifdef _WIN32
- fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0666);
+ int fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0666);
if (fd == -1) {
- saved_errno = errno;
+ int saved_errno = errno;
cc_log("lockfile_acquire: open WRONLY %s: %s", lockfile, strerror(errno));
if (saved_errno == ENOENT) {
// Directory doesn't exist?
}
}
free(content);
+ const size_t bufsize = 1024;
content = x_malloc(bufsize);
- if ((len = read(fd, content, bufsize - 1)) == -1) {
+ int len = read(fd, content, bufsize - 1);
+ if (len == -1) {
cc_log("lockfile_acquire: read %s: %s", lockfile, strerror(errno));
close(fd);
goto out;
goto out;
}
#else
- ret = symlink(my_content, lockfile);
- if (ret == 0) {
+ if (symlink(my_content, lockfile) == 0) {
// We got the lock.
acquired = true;
goto out;
}
- saved_errno = errno;
+ int saved_errno = errno;
cc_log("lockfile_acquire: symlink %s: %s", lockfile, strerror(saved_errno));
if (saved_errno == ENOENT) {
// Directory doesn't exist?
static void
free_manifest(struct manifest *mf)
{
- uint32_t i;
- for (i = 0; i < mf->n_files; i++) {
+ for (uint32_t i = 0; i < mf->n_files; i++) {
free(mf->files[i]);
}
free(mf->files);
free(mf->file_infos);
- for (i = 0; i < mf->n_objects; i++) {
+ for (uint32_t i = 0; i < mf->n_objects; i++) {
free(mf->objects[i].file_info_indexes);
}
free(mf->objects);
#define READ_BYTE(var) \
do { \
- int ch_; \
- ch_ = gzgetc(f); \
+ int ch_ = gzgetc(f); \
if (ch_ == EOF) { \
goto error; \
} \
#define READ_INT(size, var) \
do { \
- int ch_; \
- size_t i_; \
(var) = 0; \
- for (i_ = 0; i_ < (size); i_++) { \
- ch_ = gzgetc(f); \
+ for (size_t i_ = 0; i_ < (size); i_++) { \
+ int ch_ = gzgetc(f); \
if (ch_ == EOF) { \
goto error; \
} \
do { \
char buf_[1024]; \
size_t i_; \
- int ch_; \
for (i_ = 0; i_ < sizeof(buf_); i_++) { \
- ch_ = gzgetc(f); \
+ int ch_ = gzgetc(f); \
if (ch_ == EOF) { \
goto error; \
} \
#define READ_BYTES(n, var) \
do { \
- size_t i_; \
- int ch_; \
- for (i_ = 0; i_ < (n); i_++) { \
- ch_ = gzgetc(f); \
+ for (size_t i_ = 0; i_ < (n); i_++) { \
+ int ch_ = gzgetc(f); \
if (ch_ == EOF) { \
goto error; \
} \
static struct manifest *
create_empty_manifest(void)
{
- struct manifest *mf;
-
- mf = x_malloc(sizeof(*mf));
+ struct manifest *mf = x_malloc(sizeof(*mf));
mf->hash_size = 16;
mf->n_files = 0;
mf->files = NULL;
static struct manifest *
read_manifest(gzFile f)
{
- struct manifest *mf;
- uint32_t i, j;
- uint32_t magic;
-
- mf = create_empty_manifest();
+ struct manifest *mf = create_empty_manifest();
+ uint32_t magic;
READ_INT(4, magic);
if (magic != MAGIC) {
cc_log("Manifest file has bad magic number %u", magic);
- free_manifest(mf);
- return NULL;
+ goto error;
}
+
READ_BYTE(mf->version);
if (mf->version != MANIFEST_VERSION) {
cc_log("Manifest file has unknown version %u", mf->version);
- free_manifest(mf);
- return NULL;
+ goto error;
}
READ_BYTE(mf->hash_size);
if (mf->hash_size != 16) {
// Temporary measure until we support different hash algorithms.
cc_log("Manifest file has unsupported hash size %u", mf->hash_size);
- free_manifest(mf);
- return NULL;
+ goto error;
}
READ_INT(2, mf->reserved);
READ_INT(4, mf->n_files);
mf->files = x_calloc(mf->n_files, sizeof(*mf->files));
- for (i = 0; i < mf->n_files; i++) {
+ for (uint32_t i = 0; i < mf->n_files; i++) {
READ_STR(mf->files[i]);
}
READ_INT(4, mf->n_file_infos);
mf->file_infos = x_calloc(mf->n_file_infos, sizeof(*mf->file_infos));
- for (i = 0; i < mf->n_file_infos; i++) {
+ for (uint32_t i = 0; i < mf->n_file_infos; i++) {
READ_INT(4, mf->file_infos[i].index);
READ_BYTES(mf->hash_size, mf->file_infos[i].hash);
READ_INT(4, mf->file_infos[i].size);
READ_INT(4, mf->n_objects);
mf->objects = x_calloc(mf->n_objects, sizeof(*mf->objects));
- for (i = 0; i < mf->n_objects; i++) {
+ for (uint32_t i = 0; i < mf->n_objects; i++) {
READ_INT(4, mf->objects[i].n_file_info_indexes);
mf->objects[i].file_info_indexes =
x_calloc(mf->objects[i].n_file_info_indexes,
sizeof(*mf->objects[i].file_info_indexes));
- for (j = 0; j < mf->objects[i].n_file_info_indexes; j++) {
+ for (uint32_t j = 0; j < mf->objects[i].n_file_info_indexes; j++) {
READ_INT(4, mf->objects[i].file_info_indexes[j]);
}
READ_BYTES(mf->hash_size, mf->objects[i].hash.hash);
static int
write_manifest(gzFile f, const struct manifest *mf)
{
- uint32_t i, j;
-
WRITE_INT(4, MAGIC);
WRITE_INT(1, MANIFEST_VERSION);
WRITE_INT(1, 16);
WRITE_INT(2, 0);
WRITE_INT(4, mf->n_files);
- for (i = 0; i < mf->n_files; i++) {
+ for (uint32_t i = 0; i < mf->n_files; i++) {
WRITE_STR(mf->files[i]);
}
WRITE_INT(4, mf->n_file_infos);
- for (i = 0; i < mf->n_file_infos; i++) {
+ for (uint32_t i = 0; i < mf->n_file_infos; i++) {
WRITE_INT(4, mf->file_infos[i].index);
WRITE_BYTES(mf->hash_size, mf->file_infos[i].hash);
WRITE_INT(4, mf->file_infos[i].size);
}
WRITE_INT(4, mf->n_objects);
- for (i = 0; i < mf->n_objects; i++) {
+ for (uint32_t i = 0; i < mf->n_objects; i++) {
WRITE_INT(4, mf->objects[i].n_file_info_indexes);
- for (j = 0; j < mf->objects[i].n_file_info_indexes; j++) {
+ for (uint32_t j = 0; j < mf->objects[i].n_file_info_indexes; j++) {
WRITE_INT(4, mf->objects[i].file_info_indexes[j]);
}
WRITE_BYTES(mf->hash_size, mf->objects[i].hash.hash);
verify_object(struct conf *conf, struct manifest *mf, struct object *obj,
struct hashtable *stated_files, struct hashtable *hashed_files)
{
- uint32_t i;
- struct file_hash *actual;
- struct mdfour hash;
- int result;
-
- for (i = 0; i < obj->n_file_info_indexes; i++) {
+ for (uint32_t i = 0; i < obj->n_file_info_indexes; i++) {
struct file_info *fi = &mf->file_infos[obj->file_info_indexes[i]];
char *path = mf->files[fi->index];
struct file_stats *st = hashtable_search(stated_files, path);
}
}
- actual = hashtable_search(hashed_files, path);
+ struct file_hash *actual = hashtable_search(hashed_files, path);
if (!actual) {
- actual = x_malloc(sizeof(*actual));
+ struct mdfour hash;
hash_start(&hash);
- result = hash_source_code_file(conf, &hash, path);
+ int result = hash_source_code_file(conf, &hash, path);
if (result & HASH_SOURCE_CODE_ERROR) {
cc_log("Failed hashing %s", path);
- free(actual);
return 0;
}
if (result & HASH_SOURCE_CODE_FOUND_TIME) {
- free(actual);
return 0;
}
+ actual = x_malloc(sizeof(*actual));
hash_result_as_bytes(&hash, actual->hash);
actual->size = hash.totalN;
hashtable_insert(hashed_files, x_strdup(path), actual);
static struct hashtable *
create_string_index_map(char **strings, uint32_t len)
{
- uint32_t i;
- struct hashtable *h;
- uint32_t *index;
-
- h = create_hashtable(1000, hash_from_string, strings_equal);
- for (i = 0; i < len; i++) {
- index = x_malloc(sizeof(*index));
+ struct hashtable *h =
+ create_hashtable(1000, hash_from_string, strings_equal);
+ for (uint32_t i = 0; i < len; i++) {
+ uint32_t *index = x_malloc(sizeof(*index));
*index = i;
hashtable_insert(h, x_strdup(strings[i]), index);
}
static struct hashtable *
create_file_info_index_map(struct file_info *infos, uint32_t len)
{
- uint32_t i;
- struct hashtable *h;
- struct file_info *fi;
- uint32_t *index;
-
- h = create_hashtable(1000, hash_from_file_info, file_infos_equal);
- for (i = 0; i < len; i++) {
- fi = x_malloc(sizeof(*fi));
+ struct hashtable *h =
+ create_hashtable(1000, hash_from_file_info, file_infos_equal);
+ for (uint32_t i = 0; i < len; i++) {
+ struct file_info *fi = x_malloc(sizeof(*fi));
*fi = infos[i];
- index = x_malloc(sizeof(*index));
+ uint32_t *index = x_malloc(sizeof(*index));
*index = i;
hashtable_insert(h, fi, index);
}
get_include_file_index(struct manifest *mf, char *path,
struct hashtable *mf_files)
{
- uint32_t *index;
- uint32_t n;
-
- index = hashtable_search(mf_files, path);
+ uint32_t *index = hashtable_search(mf_files, path);
if (index) {
return *index;
}
- n = mf->n_files;
+ uint32_t n = mf->n_files;
mf->files = x_realloc(mf->files, (n + 1) * sizeof(*mf->files));
mf->n_files++;
mf->files[n] = x_strdup(path);
-
return n;
}
struct hashtable *mf_file_infos)
{
struct file_info fi;
- uint32_t *fi_index;
- uint32_t n;
- struct stat file_stat;
-
fi.index = get_include_file_index(mf, path, mf_files);
memcpy(fi.hash, file_hash->hash, sizeof(fi.hash));
fi.size = file_hash->size;
// st->ctime may be 0, so we have to check time_of_compilation against
// MAX(mtime, ctime).
+ struct stat file_stat;
if (stat(path, &file_stat) != -1
&& time_of_compilation > MAX(file_stat.st_mtime, file_stat.st_ctime)) {
fi.mtime = file_stat.st_mtime;
fi.ctime = -1;
}
- fi_index = hashtable_search(mf_file_infos, &fi);
+ uint32_t *fi_index = hashtable_search(mf_file_infos, &fi);
if (fi_index) {
return *fi_index;
}
- n = mf->n_file_infos;
+ uint32_t n = mf->n_file_infos;
mf->file_infos = x_realloc(mf->file_infos, (n + 1) * sizeof(*mf->file_infos));
mf->n_file_infos++;
mf->file_infos[n] = fi;
-
return n;
}
add_file_info_indexes(uint32_t *indexes, uint32_t size,
struct manifest *mf, struct hashtable *included_files)
{
- struct hashtable_itr *iter;
- uint32_t i;
- struct hashtable *mf_files; // path --> index
- struct hashtable *mf_file_infos; // struct file_info --> index
-
if (size == 0) {
return;
}
- mf_files = create_string_index_map(mf->files, mf->n_files);
- mf_file_infos = create_file_info_index_map(mf->file_infos, mf->n_file_infos);
- iter = hashtable_iterator(included_files);
- i = 0;
+ // path --> index
+ struct hashtable *mf_files =
+ create_string_index_map(mf->files, mf->n_files);
+ // struct file_info --> index
+ struct hashtable *mf_file_infos =
+ create_file_info_index_map(mf->file_infos, mf->n_file_infos);
+ struct hashtable_itr *iter = hashtable_iterator(included_files);
+ uint32_t i = 0;
do {
char *path = hashtable_iterator_key(iter);
struct file_hash *file_hash = hashtable_iterator_value(iter);
struct file_hash *object_hash,
struct hashtable *included_files)
{
- struct object *obj;
- uint32_t n;
-
- n = mf->n_objects;
- mf->objects = x_realloc(mf->objects, (n + 1) * sizeof(*mf->objects));
+ uint32_t n_objs = mf->n_objects;
+ mf->objects = x_realloc(mf->objects, (n_objs + 1) * sizeof(*mf->objects));
mf->n_objects++;
- obj = &mf->objects[n];
+ struct object *obj = &mf->objects[n_objs];
- n = hashtable_count(included_files);
- obj->n_file_info_indexes = n;
- obj->file_info_indexes = x_malloc(n * sizeof(*obj->file_info_indexes));
- add_file_info_indexes(obj->file_info_indexes, n, mf, included_files);
+ uint32_t n_fii = hashtable_count(included_files);
+ obj->n_file_info_indexes = n_fii;
+ obj->file_info_indexes = x_malloc(n_fii * sizeof(*obj->file_info_indexes));
+ add_file_info_indexes(obj->file_info_indexes, n_fii, mf, included_files);
memcpy(obj->hash.hash, object_hash->hash, mf->hash_size);
obj->hash.size = object_hash->size;
}
struct file_hash *
manifest_get(struct conf *conf, const char *manifest_path)
{
- int fd;
gzFile f = NULL;
struct manifest *mf = NULL;
struct hashtable *hashed_files = NULL; // path --> struct file_hash
struct hashtable *stated_files = NULL; // path --> struct file_stats
- uint32_t i;
struct file_hash *fh = NULL;
- fd = open(manifest_path, O_RDONLY | O_BINARY);
+ int fd = open(manifest_path, O_RDONLY | O_BINARY);
if (fd == -1) {
// Cache miss.
cc_log("No such manifest file");
stated_files = create_hashtable(1000, hash_from_string, strings_equal);
// Check newest object first since it's a bit more likely to match.
- for (i = mf->n_objects; i > 0; i--) {
+ for (uint32_t i = mf->n_objects; i > 0; i--) {
if (verify_object(conf, mf, &mf->objects[i - 1],
stated_files, hashed_files)) {
fh = x_malloc(sizeof(*fh));
struct hashtable *included_files)
{
int ret = 0;
- int fd1;
- int fd2;
gzFile f2 = NULL;
struct manifest *mf = NULL;
char *tmp_file = NULL;
// race between two processes will only result in one lost entry, which is
// not a big deal, and it's also very unlikely.
- fd1 = open(manifest_path, O_RDONLY | O_BINARY);
+ int fd1 = open(manifest_path, O_RDONLY | O_BINARY);
if (fd1 == -1) {
// New file.
mf = create_empty_manifest();
}
tmp_file = format("%s.tmp", manifest_path);
- fd2 = create_tmp_fd(&tmp_file);
+ int fd2 = create_tmp_fd(&tmp_file);
f2 = gzdopen(fd2, "wb");
if (!f2) {
cc_log("Failed to gzdopen %s", tmp_file);
manifest_dump(const char *manifest_path, FILE *stream)
{
struct manifest *mf = NULL;
- int fd;
gzFile f = NULL;
bool ret = false;
- unsigned i, j;
- fd = open(manifest_path, O_RDONLY | O_BINARY);
+ int fd = open(manifest_path, O_RDONLY | O_BINARY);
if (fd == -1) {
fprintf(stderr, "No such manifest file: %s\n", manifest_path);
goto out;
fprintf(stream, "Hash size: %u\n", (unsigned)mf->hash_size);
fprintf(stream, "Reserved field: %u\n", (unsigned)mf->reserved);
fprintf(stream, "File paths (%u):\n", (unsigned)mf->n_files);
- for (i = 0; i < mf->n_files; ++i) {
+ for (unsigned i = 0; i < mf->n_files; ++i) {
fprintf(stream, " %u: %s\n", i, mf->files[i]);
}
fprintf(stream, "File infos (%u):\n", (unsigned)mf->n_file_infos);
- for (i = 0; i < mf->n_file_infos; ++i) {
+ for (unsigned i = 0; i < mf->n_file_infos; ++i) {
char *hash;
fprintf(stream, " %u:\n", i);
fprintf(stream, " Path index: %u\n", mf->file_infos[i].index);
fprintf(stream, " Ctime: %lld\n", (long long)mf->file_infos[i].ctime);
}
fprintf(stream, "Results (%u):\n", (unsigned)mf->n_objects);
- for (i = 0; i < mf->n_objects; ++i) {
+ for (unsigned i = 0; i < mf->n_objects; ++i) {
char *hash;
fprintf(stream, " %u:\n", i);
fprintf(stream, " File info indexes:");
- for (j = 0; j < mf->objects[i].n_file_info_indexes; ++j) {
+ for (unsigned j = 0; j < mf->objects[i].n_file_info_indexes; ++j) {
fprintf(stream, " %u", mf->objects[i].file_info_indexes[j]);
}
fprintf(stream, "\n");
uint32_t AA, BB, CC, DD;
uint32_t A, B, C, D;
- A = m->A; B = m->B; C = m->C; D = m->D;
- AA = A; BB = B; CC = C; DD = D;
+ A = m->A;
+ B = m->B;
+ C = m->C;
+ D = m->D;
+ AA = A;
+ BB = B;
+ CC = C;
+ DD = D;
ROUND1(A, B, C, D, 0, 3); ROUND1(D, A, B, C, 1, 7);
ROUND1(C, D, A, B, 2, 11); ROUND1(B, C, D, A, 3, 19);
ROUND3(A, B, C, D, 3, 3); ROUND3(D, A, B, C, 11, 9);
ROUND3(C, D, A, B, 7, 11); ROUND3(B, C, D, A, 15, 15);
- A += AA; B += BB;
- C += CC; D += DD;
+ A += AA;
+ B += BB;
+ C += CC;
+ D += DD;
- A &= MASK32; B &= MASK32;
- C &= MASK32; D &= MASK32;
+ A &= MASK32;
+ B &= MASK32;
+ C &= MASK32;
+ D &= MASK32;
- m->A = A; m->B = B; m->C = C; m->D = D;
+ m->A = A;
+ m->B = B;
+ m->C = C;
+ m->D = D;
}
static void
copy64(uint32_t *M, const unsigned char *in)
{
#ifdef WORDS_BIGENDIAN
- int i;
-
- for (i = 0; i < 16; i++) {
+ for (int i = 0; i < 16; i++) {
M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
(in[i*4+1]<<8) | (in[i*4+0]<<0);
}
static
void mdfour_tail(const unsigned char *in, size_t n)
{
+ m->totalN += n;
+ uint32_t b = m->totalN * 8;
unsigned char buf[128] = { 0 };
uint32_t M[16];
- uint32_t b;
-
- m->totalN += n;
-
- b = m->totalN * 8;
-
if (n) {
memcpy(buf, in, n);
}
void
mdfour_update(struct mdfour *md, const unsigned char *in, size_t n)
{
- uint32_t M[16];
-
#ifdef CCACHE_DEBUG_HASH
if (getenv("CCACHE_DEBUG_HASH")) {
FILE *f = fopen("ccache-debug-hash.bin", "a");
return;
}
+ uint32_t M[16];
if (md->tail_len) {
size_t len = 64 - md->tail_len;
if (len > n) {
{
const unsigned int m = 0x5bd1e995;
const int r = 24;
-
unsigned int h = seed ^ len;
-
const unsigned char *data = (const unsigned char *)key;
while (len >= 4) {
- unsigned int k;
-
- k = data[0];
+ unsigned int k = data[0];
k |= data[1] << 8;
k |= data[2] << 16;
k |= data[3] << 24;
parse_stats(struct counters *counters, const char *buf)
{
size_t i = 0;
- const char *p;
- char *p2;
-
- p = buf;
+ const char *p = buf;
while (true) {
+ char *p2;
long val = strtol(p, &p2, 10);
if (p2 == p) {
break;
void
stats_write(const char *path, struct counters *counters)
{
- size_t i;
- char *tmp_file;
- FILE *f;
-
- tmp_file = format("%s.tmp", path);
- f = create_tmp_file(&tmp_file, "wb");
- for (i = 0; i < counters->size; i++) {
+ char *tmp_file = format("%s.tmp", path);
+ FILE *f = create_tmp_file(&tmp_file, "wb");
+ for (size_t i = 0; i < counters->size; i++) {
if (fprintf(f, "%u\n", counters->data[i]) < 0) {
fatal("Failed to write to %s", tmp_file);
}
void
stats_flush(void)
{
- struct counters *counters;
- bool need_cleanup = false;
- bool should_flush = false;
- int i;
-
assert(conf);
if (!conf->stats) {
return;
}
- for (i = 0; i < STATS_END; ++i) {
+ bool should_flush = false;
+ for (int i = 0; i < STATS_END; ++i) {
if (counter_updates->data[i] > 0) {
should_flush = true;
break;
if (!lockfile_acquire(stats_file, lock_staleness_limit)) {
return;
}
- counters = counters_init(STATS_END);
+
+ struct counters *counters = counters_init(STATS_END);
stats_read(stats_file, counters);
- for (i = 0; i < STATS_END; ++i) {
+ for (int i = 0; i < STATS_END; ++i) {
counters->data[i] += counter_updates->data[i];
}
stats_write(stats_file, counters);
lockfile_release(stats_file);
if (!str_eq(conf->log_file, "")) {
- for (i = 0; i < STATS_END; ++i) {
+ for (int i = 0; i < STATS_END; ++i) {
if (counter_updates->data[stats_info[i].stat] != 0
&& !(stats_info[i].flags & FLAG_NOZERO)) {
cc_log("Result: %s", stats_info[i].message);
}
}
+ bool need_cleanup = false;
if (conf->max_files != 0
&& counters->data[STATS_NUMFILES] > conf->max_files / 16) {
need_cleanup = true;
void
stats_summary(struct conf *conf)
{
- int dir, i;
struct counters *counters = counters_init(STATS_END);
- unsigned direct = 0, preprocessed = 0;
- unsigned hit, miss, total;
- double percent;
assert(conf);
// Add up the stats in each directory.
- for (dir = -1; dir <= 0xF; dir++) {
+ for (int dir = -1; dir <= 0xF; dir++) {
char *fname;
if (dir == -1) {
secondary_config_path ? secondary_config_path : "");
// ...and display them.
- for (i = 0; stats_info[i].message; i++) {
+ for (int i = 0; stats_info[i].message; i++) {
enum stats stat = stats_info[i].stat;
if (stats_info[i].flags & FLAG_NEVER) {
printf("%8u\n", counters->data[stat]);
}
+ unsigned direct = 0;
+ unsigned preprocessed = 0;
if (stat == STATS_CACHEHIT_DIR) {
direct = counters->data[stat];
} else if (stat == STATS_CACHEHIT_CPP) {
preprocessed = counters->data[stat];
} else if (stat == STATS_TOCACHE) {
- miss = counters->data[stat];
- hit = direct + preprocessed;
- total = hit + miss;
- if (total > 0) {
- percent = (100.0f * hit) / total;
- } else {
- percent = 0.0f;
- }
+ unsigned miss = counters->data[stat];
+ unsigned hit = direct + preprocessed;
+ unsigned total = hit + miss;
+ double percent = total > 0 ? (100.0f * hit) / total : 0.0f;
printf("cache hit rate %6.2f %%\n", percent);
}
}
void
stats_zero(void)
{
- int dir;
- unsigned i;
- char *fname;
-
assert(conf);
- fname = format("%s/stats", conf->cache_dir);
+ char *fname = format("%s/stats", conf->cache_dir);
x_unlink(fname);
free(fname);
- for (dir = 0; dir <= 0xF; dir++) {
+ for (int dir = 0; dir <= 0xF; dir++) {
struct counters *counters = counters_init(STATS_END);
struct stat st;
fname = format("%s/%1x/stats", conf->cache_dir, dir);
}
if (lockfile_acquire(fname, lock_staleness_limit)) {
stats_read(fname, counters);
- for (i = 0; stats_info[i].message; i++) {
+ for (unsigned i = 0; stats_info[i].message; i++) {
if (!(stats_info[i].flags & FLAG_NOZERO)) {
counters->data[stats_info[i].stat] = 0;
}
stats_set_sizes(const char *dir, unsigned num_files, uint64_t total_size)
{
struct counters *counters = counters_init(STATS_END);
- char *statsfile;
-
- statsfile = format("%s/stats", dir);
-
+ char *statsfile = format("%s/stats", dir);
if (lockfile_acquire(statsfile, lock_staleness_limit)) {
stats_read(statsfile, counters);
counters->data[STATS_NUMFILES] = num_files;
stats_add_cleanup(const char *dir, unsigned count)
{
struct counters *counters = counters_init(STATS_END);
- char *statsfile;
-
- statsfile = format("%s/stats", dir);
-
+ char *statsfile = format("%s/stats", dir);
if (lockfile_acquire(statsfile, lock_staleness_limit)) {
stats_read(statsfile, counters);
counters->data[STATS_NUMCLEANUPS] += count;
static void
build_table(void)
{
- unsigned char c;
- int i;
static bool done;
-
if (done) {
return;
}
done = true;
memset(tokens, 0, sizeof(tokens));
- for (c = 0; c < 128; c++) {
+ for (unsigned char c = 0; c < 128; c++) {
if (isalpha(c) || c == '_') {
tokens[c].type |= C_ALPHA;
}
tokens['-'].type |= C_SIGN;
tokens['+'].type |= C_SIGN;
- for (i = 0; s_tokens[i]; i++) {
- c = s_tokens[i][0];
+ for (int i = 0; s_tokens[i]; i++) {
+ unsigned char c = s_tokens[i][0];
tokens[c].type |= C_TOKEN;
tokens[c].toks[tokens[c].num_toks] = s_tokens[i];
tokens[c].num_toks++;
static void
unify(struct mdfour *hash, unsigned char *p, size_t size)
{
- size_t ofs;
- unsigned char q;
- int i;
-
build_table();
- for (ofs = 0; ofs < size; ) {
+ for (size_t ofs = 0; ofs < size; ) {
if (p[ofs] == '#') {
if ((size-ofs) > 2 && p[ofs+1] == ' ' && isdigit(p[ofs+2])) {
do {
}
if (tokens[p[ofs]].type & C_QUOTE) {
- q = p[ofs];
+ unsigned char q = p[ofs];
pushchar(hash, p[ofs]);
do {
ofs++;
}
if (tokens[p[ofs]].type & C_TOKEN) {
- q = p[ofs];
+ unsigned char q = p[ofs];
+ int i;
for (i = 0; i < tokens[q].num_toks; i++) {
unsigned char *s = (unsigned char *)tokens[q].toks[i];
int len = strlen((char *)s);
{
char *data;
size_t size;
-
if (!read_file(fname, 0, &data, &size)) {
stats_update(STATS_PREPROCESSOR);
return -1;
return MAXPATHLEN;
#elif defined(_PC_PATH_MAX)
long maxlen = pathconf(path, _PC_PATH_MAX);
- if (maxlen >= 4096) {
- return maxlen;
- } else {
- return 4096;
- }
+ return maxlen >= 4096 ? maxlen : 4096;
#endif
}
static void
vlog(const char *format, va_list ap, bool log_updated_time)
{
- int rc1, rc2;
if (!init_log()) {
return;
}
log_prefix(log_updated_time);
- rc1 = vfprintf(logfile, format, ap);
- rc2 = fprintf(logfile, "\n");
+ int rc1 = vfprintf(logfile, format, ap);
+ int rc2 = fprintf(logfile, "\n");
if (rc1 < 0 || rc2 < 0) {
warn_log_fail();
}
void
cc_log_argv(const char *prefix, char **argv)
{
- int rc;
if (!init_log()) {
return;
}
log_prefix(true);
fputs(prefix, logfile);
print_command(logfile, argv);
- rc = fflush(logfile);
+ int rc = fflush(logfile);
if (rc) {
warn_log_fail();
}
fatal(const char *format, ...)
{
va_list ap;
- char msg[1000];
-
va_start(ap, format);
+ char msg[1000];
vsnprintf(msg, sizeof(msg), format, ap);
va_end(ap);
void
copy_fd(int fd_in, int fd_out)
{
- char buf[10240];
- int n;
- gzFile gz_in;
-
- gz_in = gzdopen(dup(fd_in), "rb");
-
+ gzFile gz_in = gzdopen(dup(fd_in), "rb");
if (!gz_in) {
fatal("Failed to copy fd");
}
+ int n;
+ char buf[10240];
while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
ssize_t written = 0;
do {
int
copy_file(const char *src, const char *dest, int compress_level)
{
- int fd_in, fd_out;
- gzFile gz_in = NULL, gz_out = NULL;
- char buf[10240];
- int n, written;
- char *tmp_name;
- struct stat st;
- int errnum;
+ int fd_out;
+ gzFile gz_in = NULL;
+ gzFile gz_out = NULL;
int saved_errno = 0;
// Open destination file.
- tmp_name = x_strdup(dest);
+ char *tmp_name = x_strdup(dest);
fd_out = create_tmp_fd(&tmp_name);
cc_log("Copying %s to %s via %s (%scompressed)",
src, dest, tmp_name, compress_level > 0 ? "" : "un");
// Open source file.
- fd_in = open(src, O_RDONLY | O_BINARY);
+ int fd_in = open(src, O_RDONLY | O_BINARY);
if (fd_in == -1) {
saved_errno = errno;
cc_log("open error: %s", strerror(saved_errno));
// A gzip file occupies at least 20 bytes, so it will always occupy an
// entire filesystem block, even for empty files. Turn off compression for
// empty files to save some space.
+ struct stat st;
if (x_fstat(fd_in, &st) != 0) {
goto error;
}
gzsetparams(gz_out, compress_level, Z_DEFAULT_STRATEGY);
}
+ int n;
+ char buf[10240];
while ((n = gzread(gz_in, buf, sizeof(buf))) > 0) {
+ int written;
if (compress_level > 0) {
written = gzwrite(gz_out, buf, n);
} else {
}
if (written != n) {
if (compress_level > 0) {
+ int errnum;
cc_log("gzwrite error: %s (errno: %s)",
gzerror(gz_in, &errnum),
strerror(saved_errno));
// gzeof won't tell if there's an error in the trailing CRC, so we must check
// gzerror before considering everything OK.
+ int errnum;
gzerror(gz_in, &errnum);
if (!gzeof(gz_in) || (errnum != Z_OK && errnum != Z_STREAM_END)) {
saved_errno = errno;
int
move_file(const char *src, const char *dest, int compress_level)
{
- int ret;
-
- ret = copy_file(src, dest, compress_level);
+ int ret = copy_file(src, dest, compress_level);
if (ret != -1) {
x_unlink(src);
}
bool
file_is_compressed(const char *filename)
{
- FILE *f;
-
- f = fopen(filename, "rb");
+ FILE *f = fopen(filename, "rb");
if (!f) {
return false;
}
int
create_parent_dirs(const char *path)
{
- struct stat st;
int res;
char *parent = dirname(path);
-
+ struct stat st;
if (stat(parent, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
res = 0;
return hostname;
}
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- wVersionRequested = MAKEWORD(2, 2);
-
- err = WSAStartup(wVersionRequested, &wsaData);
+ WORD w_version_requested = MAKEWORD(2, 2);
+ WSADATA wsa_data;
+ int err = WSAStartup(w_version_requested, &wsa_data);
if (err != 0) {
// Tell the user that we could not find a usable Winsock DLL.
cc_log("WSAStartup failed with error: %d", err);
return hostname;
}
- if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
+ if (LOBYTE(wsa_data.wVersion) != 2 || HIBYTE(wsa_data.wVersion) != 2) {
// Tell the user that we could not find a usable WinSock DLL.
cc_log("Could not find a usable version of Winsock.dll");
WSACleanup();
int result = gethostname(hostname, sizeof(hostname) - 1);
if (result != 0) {
- int last_error = WSAGetLastError();
- LPVOID lpMsgBuf;
- LPVOID lpDisplayBuf;
- DWORD dw = last_error;
+ LPVOID lp_msg_buf;
+ DWORD dw = WSAGetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf, 0, NULL);
+ (LPTSTR) &lp_msg_buf, 0, NULL);
- lpDisplayBuf = (LPVOID) LocalAlloc(
+ LPVOID lp_display_buf = (LPVOID) LocalAlloc(
LMEM_ZEROINIT,
- (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 200)
+ (lstrlen((LPCTSTR) lp_msg_buf) + lstrlen((LPCTSTR) __FILE__) + 200)
* sizeof(TCHAR));
- _snprintf((LPTSTR) lpDisplayBuf,
- LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+ _snprintf((LPTSTR) lp_display_buf,
+ LocalSize(lp_display_buf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"), __FILE__, dw,
- lpMsgBuf);
+ lp_msg_buf);
- cc_log("can't get hostname OS returned error: %s", (char *)lpDisplayBuf);
+ cc_log("can't get hostname OS returned error: %s", (char *)lp_display_buf);
- LocalFree(lpMsgBuf);
- LocalFree(lpDisplayBuf);
+ LocalFree(lp_msg_buf);
+ LocalFree(lp_display_buf);
}
WSACleanup();
#endif
tmp_string(void)
{
static char *ret;
-
if (!ret) {
ret = format("%s.%u.XXXXXX", get_hostname(), (unsigned)getpid());
}
-
return ret;
}
char *
format_hash_as_string(const unsigned char *hash, int size)
{
- char *ret;
int i;
-
- ret = x_malloc(53);
+ char *ret = x_malloc(53);
for (i = 0; i < 16; i++) {
sprintf(&ret[i*2], "%02x", (unsigned) hash[i]);
}
if (size >= 0) {
sprintf(&ret[i*2], "-%d", size);
}
-
return ret;
}
"Signature: 8a477f597d28d172789f06886806bc55\n"
"# This file is a cache directory tag created by ccache.\n"
"# For information about cache directory tags, see:\n"
- "# http://www.brynosaurus.com/cachedir/\n";
+ "#\thttp://www.brynosaurus.com/cachedir/\n";
int
create_cachedirtag(const char *dir)
{
- struct stat st;
- FILE *f;
char *filename = format("%s/CACHEDIR.TAG", dir);
+ struct stat st;
if (stat(filename, &st) == 0) {
if (S_ISREG(st.st_mode)) {
goto success;
errno = EEXIST;
goto error;
}
- f = fopen(filename, "w");
+ FILE *f = fopen(filename, "w");
if (!f) {
goto error;
}
format(const char *format, ...)
{
va_list ap;
- char *ptr = NULL;
-
va_start(ap, format);
+
+ char *ptr = NULL;
if (vasprintf(&ptr, format, ap) == -1) {
fatal("Out of memory in format");
}
char *
x_strdup(const char *s)
{
- char *ret;
- ret = strdup(s);
+ char *ret = strdup(s);
if (!ret) {
fatal("Out of memory in x_strdup");
}
char *
x_strndup(const char *s, size_t n)
{
- char *ret;
#ifndef HAVE_STRNDUP
- size_t m;
-
if (!s) {
return NULL;
}
- m = 0;
+ size_t m = 0;
while (m < n && s[m]) {
m++;
}
- ret = malloc(m + 1);
+ char *ret = malloc(m + 1);
if (ret) {
memcpy(ret, s, m);
ret[m] = '\0';
}
#else
- ret = strndup(s, n);
+ char *ret = strndup(s, n);
#endif
if (!ret) {
fatal("x_strndup: Could not allocate %lu bytes", (unsigned long)n);
void *
x_malloc(size_t size)
{
- void *ret;
if (size == 0) {
// malloc() may return NULL if size is zero, so always do this to make sure
// that the code handles it regardless of platform.
return NULL;
}
- ret = malloc(size);
+ void *ret = malloc(size);
if (!ret) {
fatal("x_malloc: Could not allocate %lu bytes", (unsigned long)size);
}
void *
x_calloc(size_t nmemb, size_t size)
{
- void *ret;
if (nmemb * size == 0) {
// calloc() may return NULL if nmemb or size is 0, so always do this to
// make sure that the code handles it regardless of platform.
return NULL;
}
- ret = calloc(nmemb, size);
+ void *ret = calloc(nmemb, size);
if (!ret) {
fatal("x_calloc: Could not allocate %lu bytes", (unsigned long)size);
}
void *
x_realloc(void *ptr, size_t size)
{
- void *p2;
if (!ptr) {
return x_malloc(size);
}
- p2 = realloc(ptr, size);
+ void *p2 = realloc(ptr, size);
if (!p2) {
fatal("x_realloc: Could not allocate %lu bytes", (unsigned long)size);
}
reformat(char **ptr, const char *format, ...)
{
char *saved = *ptr;
- va_list ap;
-
*ptr = NULL;
+
+ va_list ap;
va_start(ap, format);
if (vasprintf(ptr, format, ap) == -1) {
fatal("Out of memory in reformat");
void
traverse(const char *dir, void (*fn)(const char *, struct stat *))
{
- DIR *d;
- struct dirent *de;
-
- d = opendir(dir);
+ DIR *d = opendir(dir);
if (!d) {
return;
}
+ struct dirent *de;
while ((de = readdir(d))) {
- char *fname;
- struct stat st;
-
if (str_eq(de->d_name, ".")) {
continue;
}
continue;
}
- fname = format("%s/%s", dir, de->d_name);
+ char *fname = format("%s/%s", dir, de->d_name);
+ struct stat st;
if (lstat(fname, &st)) {
if (errno != ENOENT && errno != ESTALE) {
fatal("lstat %s failed: %s", fname, strerror(errno));
char *
basename(const char *path)
{
- char *p;
- p = strrchr(path, '/');
+ char *p = strrchr(path, '/');
if (p) {
path = p + 1;
}
char *
dirname(const char *path)
{
- char *p;
+ char *s = x_strdup(path);
+ char *p = strrchr(s, '/');
#ifdef _WIN32
- char *p2;
-#endif
- char *s;
- s = x_strdup(path);
- p = strrchr(s, '/');
-#ifdef _WIN32
- p2 = strrchr(s, '\\');
+ char *p2 = strrchr(s, '\\');
if (!p || (p2 && p < p2)) {
p = p2;
}
get_extension(const char *path)
{
size_t len = strlen(path);
- const char *p;
-
- for (p = &path[len - 1]; p >= path; --p) {
+ for (const char *p = &path[len - 1]; p >= path; --p) {
if (*p == '.') {
return p;
}
bool
parse_size_with_suffix(const char *str, uint64_t *size)
{
- char *p;
- double x;
-
errno = 0;
- x = strtod(str, &p);
+
+ char *p;
+ double x = strtod(str, &p);
if (errno != 0 || x < 0 || p == str || *str == '\0') {
return false;
}
}
if (*p != '\0') {
- unsigned multiplier;
- if (*(p+1) == 'i') {
- multiplier = 1024;
- } else {
- multiplier = 1000;
- }
+ unsigned multiplier = *(p+1) == 'i' ? 1024 : 1000;
switch (*p) {
case 'T':
x *= multiplier;
#if defined(_WIN32) && !defined(HAVE_GETFINALPATHNAMEBYHANDLEW)
-static BOOL GetFileNameFromHandle(HANDLE hFile, TCHAR *pszFilename,
- WORD cchFilename)
+static BOOL GetFileNameFromHandle(HANDLE file_handle, TCHAR *filename,
+ WORD cch_filename)
{
- BOOL bSuccess = FALSE;
- HANDLE hFileMap;
+ BOOL success = FALSE;
// Get the file size.
- DWORD dwFileSizeHi = 0;
- DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);
-
- if (dwFileSizeLo == 0 && dwFileSizeHi == 0) {
+ DWORD file_size_hi = 0;
+ DWORD file_size_lo = GetFileSize(file_handle, &file_size_hi);
+ if (file_size_lo == 0 && file_size_hi == 0) {
// Cannot map a file with a length of zero.
return FALSE;
}
// Create a file mapping object.
- hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 1, NULL);
- if (!hFileMap) {
+ HANDLE file_map =
+ CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 1, NULL);
+ if (!file_map) {
return FALSE;
}
// Create a file mapping to get the file name.
- void *pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
- if (pMem) {
+ void *mem = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 1);
+ if (mem) {
if (GetMappedFileName(GetCurrentProcess(),
- pMem,
- pszFilename,
- cchFilename)) {
+ mem,
+ filename,
+ cch_filename)) {
// Translate path with device name to drive letters.
- TCHAR szTemp[512];
- szTemp[0] = '\0';
+ TCHAR temp[512];
+ temp[0] = '\0';
- if (GetLogicalDriveStrings(512-1, szTemp)) {
- TCHAR szName[MAX_PATH];
- TCHAR szDrive[3] = TEXT(" :");
- BOOL bFound = FALSE;
- TCHAR *p = szTemp;
+ if (GetLogicalDriveStrings(512-1, temp)) {
+ TCHAR name[MAX_PATH];
+ TCHAR drive[3] = TEXT(" :");
+ BOOL found = FALSE;
+ TCHAR *p = temp;
do {
// Copy the drive letter to the template string.
- *szDrive = *p;
+ *drive = *p;
// Look up each device name.
- if (QueryDosDevice(szDrive, szName, MAX_PATH)) {
- size_t uNameLen = _tcslen(szName);
-
- if (uNameLen < MAX_PATH) {
- bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0
- && *(pszFilename + uNameLen) == _T('\\');
- if (bFound) {
- // Reconstruct pszFilename using szTempFile and replace device
- // path with DOS path.
- TCHAR szTempFile[MAX_PATH];
- _sntprintf(szTempFile,
+ if (QueryDosDevice(drive, name, MAX_PATH)) {
+ size_t name_len = _tcslen(name);
+ if (name_len < MAX_PATH) {
+ found = _tcsnicmp(filename, name, name_len) == 0
+ && *(filename + name_len) == _T('\\');
+ if (found) {
+ // Reconstruct filename using temp_file and replace device path
+ // with DOS path.
+ TCHAR temp_file[MAX_PATH];
+ _sntprintf(temp_file,
MAX_PATH - 1,
TEXT("%s%s"),
- szDrive,
- pszFilename+uNameLen);
- _tcsncpy(pszFilename, szTempFile, _tcslen(szTempFile));
+ drive,
+ filename+name_len);
+ _tcsncpy(filename, temp_file, _tcslen(temp_file));
}
}
}
while (*p++) {
// Do nothing.
}
- } while (!bFound && *p); // End of string.
+ } while (!found && *p); // End of string.
}
}
- bSuccess = TRUE;
- UnmapViewOfFile(pMem);
+ success = TRUE;
+ UnmapViewOfFile(mem);
}
- CloseHandle(hFileMap);
- return bSuccess;
+ CloseHandle(file_map);
+ return success;
}
#endif
x_realpath(const char *path)
{
long maxlen = path_max(path);
- char *ret, *p;
-#if !defined(HAVE_REALPATH) && defined(_WIN32)
- HANDLE path_handle;
-#endif
-
- ret = x_malloc(maxlen);
+ char *ret = x_malloc(maxlen);
+ char *p;
#if HAVE_REALPATH
p = realpath(path, ret);
if (path[0] == '/') {
path++; // Skip leading slash.
}
- path_handle = CreateFile(
+ HANDLE path_handle = CreateFile(
path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE != path_handle) {
char *
strtok_r(char *str, const char *delim, char **saveptr)
{
- int len;
- char *ret;
if (!str) {
str = *saveptr;
}
- len = strlen(str);
- ret = strtok(str, delim);
+ int len = strlen(str);
+ char *ret = strtok(str, delim);
if (ret) {
char *save = ret;
while (*save++) {
char *
get_cwd(void)
{
- char *pwd;
- char *cwd;
struct stat st_pwd;
struct stat st_cwd;
- cwd = gnu_getcwd();
+ char *cwd = gnu_getcwd();
if (!cwd) {
return NULL;
}
- pwd = getenv("PWD");
+ char *pwd = getenv("PWD");
if (!pwd) {
return cwd;
}
get_relative_path(const char *from, const char *to)
{
size_t common_prefix_len;
- int i;
char *result;
assert(from && is_absolute_path(from));
if (strlen(to) > common_prefix_len) {
reformat(&result, "%s%s", result, to + common_prefix_len + 1);
}
- i = strlen(result) - 1;
- while (i >= 0 && result[i] == '/') {
+ for (int i = strlen(result) - 1; i >= 0 && result[i] == '/'; i--) {
result[i] = '\0';
- i--;
}
if (str_eq(result, "")) {
free(result);
return rename(oldpath, newpath);
#else
// Windows' rename() refuses to overwrite an existing file.
- unlink(newpath); // Not x_unlink, as x_unlink calls x_rename.
+ unlink(newpath); // Not x_unlink, as x_unlink calls x_rename.
// If the function succeeds, the return value is nonzero.
if (MoveFileA(oldpath, newpath) == 0) {
- LPVOID lpMsgBuf;
- LPVOID lpDisplayBuf;
+ LPVOID lp_msg_buf;
DWORD dw = GetLastError();
-
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
- 0, NULL);
+ NULL, dw,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lp_msg_buf,
+ 0,
+ NULL);
- lpDisplayBuf = (LPVOID) LocalAlloc(
+ LPVOID lp_display_buf = (LPVOID) LocalAlloc(
LMEM_ZEROINIT,
- (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 40)
+ (lstrlen((LPCTSTR) lp_msg_buf) + lstrlen((LPCTSTR) __FILE__) + 40)
* sizeof(TCHAR));
- _snprintf((LPTSTR) lpDisplayBuf,
- LocalSize(lpDisplayBuf) / sizeof(TCHAR),
- TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf);
+ _snprintf((LPTSTR) lp_display_buf,
+ LocalSize(lp_display_buf) / sizeof(TCHAR),
+ TEXT("%s failed with error %d: %s"), __FILE__, dw, lp_msg_buf);
cc_log("can't rename file %s to %s OS returned error: %s",
- oldpath, newpath, (char *) lpDisplayBuf);
+ oldpath, newpath, (char *) lp_display_buf);
- LocalFree(lpMsgBuf);
- LocalFree(lpDisplayBuf);
+ LocalFree(lp_msg_buf);
+ LocalFree(lp_display_buf);
return -1;
} else {
return 0;
int
tmp_unlink(const char *path)
{
- int rc;
cc_log("Unlink %s", path);
- rc = unlink(path);
+ int rc = unlink(path);
if (rc) {
cc_log("Unlink failed: %s", strerror(errno));
}
int
x_unlink(const char *path)
{
+ int saved_errno = 0;
+
// If path is on an NFS share, unlink isn't atomic, so we rename to a temp
// file. We don't care if the temp file is trashed, so it's always safe to
// unlink it first.
char *tmp_name = format("%s.rm.%s", path, tmp_string());
- int result = 0;
- int saved_errno = 0;
cc_log("Unlink %s via %s", path, tmp_name);
+
+ int result = 0;
if (x_rename(path, tmp_name) == -1) {
result = -1;
saved_errno = errno;
saved_errno = errno;
}
}
+
out:
free(tmp_name);
if (result) {
x_readlink(const char *path)
{
long maxlen = path_max(path);
- ssize_t len;
- char *buf;
-
- buf = x_malloc(maxlen);
- len = readlink(path, buf, maxlen-1);
+ char *buf = x_malloc(maxlen);
+ ssize_t len = readlink(path, buf, maxlen-1);
if (len == -1) {
free(buf);
return NULL;
bool
read_file(const char *path, size_t size_hint, char **data, size_t *size)
{
- int fd, ret;
- size_t pos = 0, allocated;
-
if (size_hint == 0) {
struct stat st;
if (x_stat(path, &st) == 0) {
}
size_hint = (size_hint < 1024) ? 1024 : size_hint;
- fd = open(path, O_RDONLY | O_BINARY);
+ int fd = open(path, O_RDONLY | O_BINARY);
if (fd == -1) {
return false;
}
- allocated = size_hint;
+ size_t allocated = size_hint;
*data = x_malloc(allocated);
+ int ret;
+ size_t pos = 0;
while (true) {
if (pos > allocated / 2) {
allocated *= 2;
{
size_t size;
char *data;
-
if (read_file(path, size_hint, &data, &size)) {
data = x_realloc(data, size + 1);
data[size] = '\0';
static bool
expand_variable(const char **str, char **result, char **errmsg)
{
- bool curly;
- const char *p, *q;
- char *name;
- const char *value;
-
assert(**str == '$');
- p = *str + 1;
+
+ bool curly;
+ const char *p = *str + 1;
if (*p == '{') {
curly = true;
++p;
} else {
curly = false;
}
- q = p;
+
+ const char *q = p;
while (isalnum(*q) || *q == '_') {
++q;
}
return true;
}
- name = x_strndup(p, q - p);
- value = getenv(name);
+ char *name = x_strndup(p, q - p);
+ const char *value = getenv(name);
if (!value) {
*errmsg = format("environment variable \"%s\" not set", name);
free(name);
char *
subst_env_in_string(const char *str, char **errmsg)
{
- const char *p; // Interval start.
- const char *q; // Interval end.
- char *result;
-
assert(errmsg);
*errmsg = NULL;
- result = x_strdup("");
- p = str;
- q = str;
+ char *result = x_strdup("");
+ const char *p = str; // Interval start.
+ const char *q = str; // Interval end.
for (q = str; *q; ++q) {
if (*q == '$') {
reformat(&result, "%s%.*s", result, (int)(q - p), p);