]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Run clang-format on all code to follow the new code style
authorJoel Rosdahl <joel@rosdahl.net>
Thu, 1 Aug 2019 22:04:30 +0000 (00:04 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 14 Aug 2019 19:42:33 +0000 (21:42 +0200)
If you end up on this commit when running “git blame ...”, it’s probably
a good idea to use “git blame -w ...” to ignore whitespace changes.

60 files changed:
.editorconfig
src/args.cpp
src/ccache.cpp
src/ccache.hpp
src/cleanup.cpp
src/common_header.cpp
src/common_header.hpp
src/compopt.cpp
src/compopt.hpp
src/compr_none.cpp
src/compr_zstd.cpp
src/compress.cpp
src/compression.cpp
src/compression.hpp
src/conf.cpp
src/conf.hpp
src/confitems.cpp
src/confitems.hpp
src/counters.cpp
src/counters.hpp
src/decompr_none.cpp
src/decompr_zstd.cpp
src/envtoconfitems.hpp
src/execute.cpp
src/exitfn.cpp
src/hash.cpp
src/hash.hpp
src/hashutil.cpp
src/hashutil.hpp
src/int_bytes_conversion.hpp
src/language.cpp
src/language.hpp
src/lockfile.cpp
src/macroskip.hpp
src/manifest.cpp
src/manifest.hpp
src/result.cpp
src/result.hpp
src/stats.cpp
src/system.hpp
src/unify.cpp
src/unify.hpp
src/util.cpp
unittest/framework.cpp
unittest/framework.hpp
unittest/main.cpp
unittest/test_args.cpp
unittest/test_argument_processing.cpp
unittest/test_compopt.cpp
unittest/test_compr_none.cpp
unittest/test_compr_zstd.cpp
unittest/test_conf.cpp
unittest/test_counters.cpp
unittest/test_hash.cpp
unittest/test_hashutil.cpp
unittest/test_lockfile.cpp
unittest/test_stats.cpp
unittest/test_util.cpp
unittest/util.cpp
unittest/util.hpp

index da20c97f75f4de6254acc3cd0ddd1c30a40947f9..8f4a31e12a651756fa8c5ed03b0216362f65efe5 100644 (file)
@@ -6,7 +6,7 @@ insert_final_newline = true
 charset = utf-8
 
 [*.{c,cpp,h,hpp}]
-indent_style = tab
+indent_style = space
 indent_size = 2
 
 [*.{bash,py}]
index 9ff7d5c3e6f36cc24a2e1ed67df8852304da7ae2..deb4309dc24fc37c5e1c21f91d262afc3a3d0a6a 100644 (file)
 
 #include "ccache.hpp"
 
-struct args *
-args_init(int init_argc, const char * const*init_args)
+struct args*
+args_init(int init_argc, const char* const* init_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 (int i = 0; i < init_argc; i++) {
-               args_add(args, init_args[i]);
-       }
-       return 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 (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_init_from_string(const charcommand)
 {
-       char *p = x_strdup(command);
-       char *q = p;
-       char *word, *saveptr = NULL;
-       struct args *args = args_init(0, NULL);
-       while ((word = strtok_r(q, " \t\r\n", &saveptr))) {
-               args_add(args, word);
-               q = NULL;
-       }
-
-       free(p);
-       return args;
+  char* p = x_strdup(command);
+  char* q = p;
+  char *word, *saveptr = NULL;
+  struct args* args = args_init(0, NULL);
+  while ((word = strtok_r(q, " \t\r\n", &saveptr))) {
+    args_add(args, word);
+    q = NULL;
+  }
+
+  free(p);
+  return args;
 }
 
-struct args *
-args_init_from_gcc_atfile(const char *filename)
+struct args*
+args_init_from_gcc_atfile(const charfilename)
 {
-       char *argtext;
-       if (!(argtext = read_text_file(filename, 0))) {
-               return NULL;
-       }
-
-       struct args *args = args_init(0, NULL);
-       char *pos = argtext;
-       char* argbuf = static_cast<char*>(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) {
-               case '\\':
-                       pos++;
-                       if (*pos == '\0') {
-                               continue;
-                       }
-                       break;
-
-               case '\"':
-               case '\'':
-                       if (quoting != '\0') {
-                               if (quoting == *pos) {
-                                       quoting = '\0';
-                                       pos++;
-                                       continue;
-                               } else {
-                                       break;
-                               }
-                       } else {
-                               quoting = *pos;
-                               pos++;
-                               continue;
-                       }
-
-               case '\n':
-               case '\r':
-               case '\t':
-               case ' ':
-                       if (quoting) {
-                               break;
-                       }
-               // Fall through.
-
-               case '\0':
-                       // End of token
-                       *argpos = '\0';
-                       if (argbuf[0] != '\0') {
-                               args_add(args, argbuf);
-                       }
-                       argpos = argbuf;
-                       if (*pos == '\0') {
-                               goto out;
-                       } else {
-                               pos++;
-                               continue;
-                       }
-               }
-
-               *argpos = *pos;
-               pos++;
-               argpos++;
-       }
+  char* argtext;
+  if (!(argtext = read_text_file(filename, 0))) {
+    return NULL;
+  }
+
+  struct args* args = args_init(0, NULL);
+  char* pos = argtext;
+  char* argbuf = static_cast<char*>(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) {
+    case '\\':
+      pos++;
+      if (*pos == '\0') {
+        continue;
+      }
+      break;
+
+    case '\"':
+    case '\'':
+      if (quoting != '\0') {
+        if (quoting == *pos) {
+          quoting = '\0';
+          pos++;
+          continue;
+        } else {
+          break;
+        }
+      } else {
+        quoting = *pos;
+        pos++;
+        continue;
+      }
+
+    case '\n':
+    case '\r':
+    case '\t':
+    case ' ':
+      if (quoting) {
+        break;
+      }
+      // Fall through.
+
+    case '\0':
+      // End of token
+      *argpos = '\0';
+      if (argbuf[0] != '\0') {
+        args_add(args, argbuf);
+      }
+      argpos = argbuf;
+      if (*pos == '\0') {
+        goto out;
+      } else {
+        pos++;
+        continue;
+      }
+    }
+
+    *argpos = *pos;
+    pos++;
+    argpos++;
+  }
 
 out:
-       free(argbuf);
-       free(argtext);
-       return args;
+  free(argbuf);
+  free(argtext);
+  return args;
 }
 
-struct args *
-args_copy(struct args *args)
+struct args*
+args_copy(struct argsargs)
 {
-       return args_init(args->argc, args->argv);
+  return args_init(args->argc, args->argv);
 }
 
 // Insert all arguments in src into dest at position index. If replace is true,
@@ -138,178 +138,175 @@ args_copy(struct args *args)
 // src is consumed by this operation and should not be freed or used again by
 // the caller.
 void
-args_insert(struct args *dest, int index, struct args *src, bool replace)
+args_insert(struct args* dest, int index, struct args* src, bool replace)
 {
-       // Adjustments made if we are replacing or shifting the element currently at
-       // dest->argv[index].
-       int offset = replace ? 1 : 0;
-
-       if (replace) {
-               free(dest->argv[index]);
-       }
-
-       if (src->argc == 0) {
-               if (replace) {
-                       // Have to shift everything down by 1 since we replaced with an empty
-                       // list.
-                       for (int i = index; i < dest->argc; i++) {
-                               dest->argv[i] = dest->argv[i + 1];
-                       }
-                       dest->argc--;
-               }
-               args_free(src);
-               return;
-       }
-
-       if (src->argc == 1 && replace) {
-               // Trivial case; replace with 1 element.
-               dest->argv[index] = src->argv[0];
-               src->argc = 0;
-               args_free(src);
-               return;
-       }
-
-       dest->argv = (char **)x_realloc(
-               dest->argv,
-               (src->argc + dest->argc + 1 - offset) * sizeof(char *));
-
-       // Shift arguments over.
-       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 (int i = 0; i < src->argc; i++) {
-               dest->argv[i + index] = src->argv[i];
-       }
-
-       dest->argc += src->argc - offset;
-       src->argc = 0;
-       args_free(src);
+  // Adjustments made if we are replacing or shifting the element currently at
+  // dest->argv[index].
+  int offset = replace ? 1 : 0;
+
+  if (replace) {
+    free(dest->argv[index]);
+  }
+
+  if (src->argc == 0) {
+    if (replace) {
+      // Have to shift everything down by 1 since we replaced with an empty
+      // list.
+      for (int i = index; i < dest->argc; i++) {
+        dest->argv[i] = dest->argv[i + 1];
+      }
+      dest->argc--;
+    }
+    args_free(src);
+    return;
+  }
+
+  if (src->argc == 1 && replace) {
+    // Trivial case; replace with 1 element.
+    dest->argv[index] = src->argv[0];
+    src->argc = 0;
+    args_free(src);
+    return;
+  }
+
+  dest->argv = (char**)x_realloc(
+    dest->argv, (src->argc + dest->argc + 1 - offset) * sizeof(char*));
+
+  // Shift arguments over.
+  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 (int i = 0; i < src->argc; i++) {
+    dest->argv[i + index] = src->argv[i];
+  }
+
+  dest->argc += src->argc - offset;
+  src->argc = 0;
+  args_free(src);
 }
 
 void
-args_free(struct args *args)
+args_free(struct argsargs)
 {
-       if (!args) {
-               return;
-       }
-       for (int i = 0; i < args->argc; ++i) {
-               if (args->argv[i]) {
-                       free(args->argv[i]);
-               }
-       }
-       free(args->argv);
-       free(args);
+  if (!args) {
+    return;
+  }
+  for (int i = 0; i < args->argc; ++i) {
+    if (args->argv[i]) {
+      free(args->argv[i]);
+    }
+  }
+  free(args->argv);
+  free(args);
 }
 
 void
-args_add(struct args *args, const char *s)
+args_add(struct args* args, const char* s)
 {
-       args->argv = (char **)x_realloc(args->argv,
-                                       (args->argc + 2) * sizeof(char *));
-       args->argv[args->argc] = x_strdup(s);
-       args->argc++;
-       args->argv[args->argc] = NULL;
+  args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char*));
+  args->argv[args->argc] = x_strdup(s);
+  args->argc++;
+  args->argv[args->argc] = NULL;
 }
 
 // Add all arguments in to_append to args.
 void
-args_extend(struct args *args, struct args *to_append)
+args_extend(struct args* args, struct args* to_append)
 {
-       for (int i = 0; i < to_append->argc; i++) {
-               args_add(args, to_append->argv[i]);
-       }
+  for (int i = 0; i < to_append->argc; i++) {
+    args_add(args, to_append->argv[i]);
+  }
 }
 
 // Pop the last element off the args list.
 void
-args_pop(struct args *args, int n)
+args_pop(struct argsargs, int n)
 {
-       while (n--) {
-               args->argc--;
-               free(args->argv[args->argc]);
-               args->argv[args->argc] = NULL;
-       }
+  while (n--) {
+    args->argc--;
+    free(args->argv[args->argc]);
+    args->argv[args->argc] = NULL;
+  }
 }
 
 // Set argument at given index.
 void
-args_set(struct args *args, int index, const char *value)
+args_set(struct args* args, int index, const char* value)
 {
-       assert(index < args->argc);
-       free(args->argv[index]);
-       args->argv[index] = x_strdup(value);
+  assert(index < args->argc);
+  free(args->argv[index]);
+  args->argv[index] = x_strdup(value);
 }
 
 // Remove the first element of the argument list.
 void
-args_remove_first(struct args *args)
+args_remove_first(struct argsargs)
 {
-       free(args->argv[0]);
-       memmove(&args->argv[0], &args->argv[1], args->argc * sizeof(args->argv[0]));
-       args->argc--;
+  free(args->argv[0]);
+  memmove(&args->argv[0], &args->argv[1], args->argc * sizeof(args->argv[0]));
+  args->argc--;
 }
 
 // Add an argument into the front of the argument list.
 void
-args_add_prefix(struct args *args, const char *s)
+args_add_prefix(struct args* args, const char* s)
 {
-       args->argv = (char **)x_realloc(args->argv,
-                                       (args->argc + 2) * sizeof(char *));
-       memmove(&args->argv[1], &args->argv[0],
-               (args->argc+1) * sizeof(args->argv[0]));
-       args->argv[0] = x_strdup(s);
-       args->argc++;
+  args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char*));
+  memmove(
+    &args->argv[1], &args->argv[0], (args->argc + 1) * sizeof(args->argv[0]));
+  args->argv[0] = x_strdup(s);
+  args->argc++;
 }
 
 // Strip any arguments beginning with the specified prefix.
 void
-args_strip(struct args *args, const char *prefix)
+args_strip(struct args* args, const char* prefix)
 {
-       for (int i = 0; i < args->argc;) {
-               if (str_startswith(args->argv[i], prefix)) {
-                       free(args->argv[i]);
-                       memmove(&args->argv[i],
-                               &args->argv[i+1],
-                               (args->argc - i) * sizeof(args->argv[i]));
-                       args->argc--;
-               } else {
-                       i++;
-               }
-       }
+  for (int i = 0; i < args->argc;) {
+    if (str_startswith(args->argv[i], prefix)) {
+      free(args->argv[i]);
+      memmove(&args->argv[i],
+              &args->argv[i + 1],
+              (args->argc - i) * sizeof(args->argv[i]));
+      args->argc--;
+    } else {
+      i++;
+    }
+  }
 }
 
 // Format args to a space-separated string. Does not quote spaces. Caller
 // frees.
-char *
-args_to_string(const struct args *args)
+char*
+args_to_string(const struct argsargs)
 {
-       unsigned size = 0;
-       for (char **p = args->argv; *p; p++) {
-               size += strlen(*p) + 1;
-       }
-
-       char* result = static_cast<char*>(x_malloc(size + 1));
-       int pos = 0;
-       for (char **p = args->argv; *p; p++) {
-               pos += sprintf(&result[pos], "%s ", *p);
-       }
-       result[pos - 1] = '\0';
-       return result;
+  unsigned size = 0;
+  for (char** p = args->argv; *p; p++) {
+    size += strlen(*p) + 1;
+  }
+
+  char* result = static_cast<char*>(x_malloc(size + 1));
+  int pos = 0;
+  for (char** p = args->argv; *p; p++) {
+    pos += sprintf(&result[pos], "%s ", *p);
+  }
+  result[pos - 1] = '\0';
+  return result;
 }
 
 // Returns true if args1 equals args2, else false.
 bool
-args_equal(const struct args *args1, const struct args *args2)
+args_equal(const struct args* args1, const struct args* args2)
 {
-       if (args1->argc != args2->argc) {
-               return false;
-       }
-       for (int i = 0; i < args1->argc; i++) {
-               if (!str_eq(args1->argv[i], args2->argv[i])) {
-                       return false;
-               }
-       }
-       return true;
+  if (args1->argc != args2->argc) {
+    return false;
+  }
+  for (int i = 0; i < args1->argc; i++) {
+    if (!str_eq(args1->argv[i], args2->argv[i])) {
+      return false;
+    }
+  }
+  return true;
 }
index 32e0477c72a20400d495fd6a5d80bf2a6b0f80d7..74207601124ca33d515e6445e443741559f26ab6 100644 (file)
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 #include "ccache.hpp"
+
 #include "compopt.hpp"
 #ifdef HAVE_GETOPT_LONG
-#include <getopt.h>
+#  include <getopt.h>
 #else
-#include "third_party/getopt_long.h"
+#  include "third_party/getopt_long.h"
 #endif
 #include "hash.hpp"
-#include "third_party/hashtable.h"
-#include "third_party/hashtable_itr.h"
 #include "hashutil.hpp"
 #include "language.hpp"
 #include "manifest.hpp"
 #include "result.hpp"
 #include "unify.hpp"
 
+#include "third_party/hashtable.h"
+#include "third_party/hashtable_itr.h"
+
 #define STRINGIFY(x) #x
 #define TO_STRING(x) STRINGIFY(x)
 
 // Global variables used by other compilation units.
-extern struct conf *conf;
-extern char *primary_config_path;
-extern char *secondary_config_path;
-extern char *current_working_dir;
-extern char *stats_file;
+extern struct confconf;
+extern charprimary_config_path;
+extern charsecondary_config_path;
+extern charcurrent_working_dir;
+extern charstats_file;
 extern unsigned lock_staleness_limit;
 
-static const char VERSION_TEXT[] =
-       MYNAME " version %s\n"
-       "\n"
-       "Copyright (C) 2002-2007 Andrew Tridgell\n"
-       "Copyright (C) 2009-2019 Joel Rosdahl and other contributors\n"
-       "\n"
-       "See <https://ccache.dev/credits.html> for a complete list of contributors.\n"
-       "\n"
-       "This program is free software; you can redistribute it and/or modify it under\n"
-       "the terms of the GNU General Public License as published by the Free Software\n"
-       "Foundation; either version 3 of the License, or (at your option) any later\n"
-       "version.\n";
+static const char VERSION_TEXT[] = MYNAME
+  " version %s\n"
+  "\n"
+  "Copyright (C) 2002-2007 Andrew Tridgell\n"
+  "Copyright (C) 2009-2019 Joel Rosdahl and other contributors\n"
+  "\n"
+  "See <https://ccache.dev/credits.html> for a complete list of "
+  "contributors.\n"
+  "\n"
+  "This program is free software; you can redistribute it and/or modify it "
+  "under\n"
+  "the terms of the GNU General Public License as published by the Free "
+  "Software\n"
+  "Foundation; either version 3 of the License, or (at your option) any "
+  "later\n"
+  "version.\n";
 
 static const char USAGE_TEXT[] =
-       "Usage:\n"
-       "    " MYNAME " [options]\n"
-       "    " MYNAME " compiler [compiler options]\n"
-       "    compiler [compiler options]          (via symbolic link)\n"
-       "\n"
-       "Common options:\n"
-       "    -c, --cleanup             delete old files and recalculate size counters\n"
-       "                              (normally not needed as this is done\n"
-       "                              automatically)\n"
-       "    -C, --clear               clear the cache completely (except configuration)\n"
-       "    -F, --max-files=N         set maximum number of files in cache to N (use 0\n"
-       "                              for no limit)\n"
-       "    -M, --max-size=SIZE       set maximum size of cache to SIZE (use 0 for no\n"
-       "                              limit); available suffixes: k, M, G, T (decimal)\n"
-       "                              and Ki, Mi, Gi, Ti (binary); default suffix: G\n"
-       "    -x, --show-compression    show compression statistics\n"
-       "    -p, --show-config         show current configuration options in\n"
-       "                              human-readable format\n"
-       "    -s, --show-stats          show summary of configuration and statistics\n"
-       "                              counters in human-readable format\n"
-       "    -z, --zero-stats          zero statistics counters\n"
-       "\n"
-       "    -h, --help                print this help text\n"
-       "    -V, --version             print version and copyright information\n"
-       "\n"
-       "Options for scripting or debugging:\n"
-       "        --dump-manifest=PATH  dump manifest file at PATH in text format\n"
-       "    -k, --get-config=K        print the value of configuration key K\n"
-       "        --hash-file=PATH      print the hash (160 bit BLAKE2b) of the file at\n"
-       "                              PATH\n"
-       "        --print-stats         print statistics counter IDs and corresponding\n"
-       "                              values in machine-parsable format\n"
-       "    -o, --set-config=K=V      set configuration item K to value V\n"
-       "\n"
-       "See also <https://ccache.dev>.\n";
+  "Usage:\n"
+  "    " MYNAME
+  " [options]\n"
+  "    " MYNAME
+  " compiler [compiler options]\n"
+  "    compiler [compiler options]          (via symbolic link)\n"
+  "\n"
+  "Common options:\n"
+  "    -c, --cleanup             delete old files and recalculate size "
+  "counters\n"
+  "                              (normally not needed as this is done\n"
+  "                              automatically)\n"
+  "    -C, --clear               clear the cache completely (except "
+  "configuration)\n"
+  "    -F, --max-files=N         set maximum number of files in cache to N "
+  "(use 0\n"
+  "                              for no limit)\n"
+  "    -M, --max-size=SIZE       set maximum size of cache to SIZE (use 0 "
+  "for no\n"
+  "                              limit); available suffixes: k, M, G, T "
+  "(decimal)\n"
+  "                              and Ki, Mi, Gi, Ti (binary); default "
+  "suffix: G\n"
+  "    -x, --show-compression    show compression statistics\n"
+  "    -p, --show-config         show current configuration options in\n"
+  "                              human-readable format\n"
+  "    -s, --show-stats          show summary of configuration and "
+  "statistics\n"
+  "                              counters in human-readable format\n"
+  "    -z, --zero-stats          zero statistics counters\n"
+  "\n"
+  "    -h, --help                print this help text\n"
+  "    -V, --version             print version and copyright information\n"
+  "\n"
+  "Options for scripting or debugging:\n"
+  "        --dump-manifest=PATH  dump manifest file at PATH in text format\n"
+  "    -k, --get-config=K        print the value of configuration key K\n"
+  "        --hash-file=PATH      print the hash (160 bit BLAKE2b) of the "
+  "file at\n"
+  "                              PATH\n"
+  "        --print-stats         print statistics counter IDs and "
+  "corresponding\n"
+  "                              values in machine-parsable format\n"
+  "    -o, --set-config=K=V      set configuration item K to value V\n"
+  "\n"
+  "See also <https://ccache.dev>.\n";
 
 // Global configuration data.
-struct conf *conf = NULL;
+struct confconf = NULL;
 
 // Where to write configuration changes.
-char *primary_config_path = NULL;
+charprimary_config_path = NULL;
 
 // Secondary, read-only configuration file (if any).
-char *secondary_config_path = NULL;
+charsecondary_config_path = NULL;
 
 // Current working directory taken from $PWD, or getcwd() if $PWD is bad.
-char *current_working_dir = NULL;
+charcurrent_working_dir = NULL;
 
 // The original argument list.
-static struct args *orig_args;
+static struct argsorig_args;
 
 // The source file.
-static char *input_file;
+static charinput_file;
 
 // The output file being compiled to.
-static char *output_obj;
+static charoutput_obj;
 
 // The path to the dependency file (implicit or specified with -MF).
-static char *output_dep;
+static charoutput_dep;
 
 // The path to the coverage file (implicit when using -ftest-coverage).
-static char *output_cov;
+static charoutput_cov;
 
 // The path to the stack usage (implicit when using -fstack-usage).
-static char *output_su;
+static charoutput_su;
 
 // Diagnostic generation information (clang). Contains pathname if not NULL.
-static char *output_dia;
+static charoutput_dia;
 
 // Split dwarf information (GCC 4.8 and up). Contains pathname if not NULL.
-static char *output_dwo;
+static charoutput_dwo;
 
 // Language to use for the compilation target (see language.c).
-static const char *actual_language;
+static const charactual_language;
 
 // Array for storing -arch options.
 #define MAX_ARCH_ARGS 10
 static size_t arch_args_size = 0;
-static char *arch_args[MAX_ARCH_ARGS] = {NULL};
+static chararch_args[MAX_ARCH_ARGS] = {NULL};
 
 // Name (represented as a struct digest) of the file containing the cached
 // result.
-static struct digest *cached_result_name;
+static struct digestcached_result_name;
 
 // Full path to the file containing the result
 // (cachedir/a/b/cdef[...]-size.result).
-static char *cached_result_path;
+static charcached_result_path;
 
 // Full path to the file containing the manifest
 // (cachedir/a/b/cdef[...]-size.manifest).
-static char *manifest_path;
+static charmanifest_path;
 
 // Time of compilation. Used to see if include files have changed after
 // compilation.
@@ -156,13 +173,13 @@ time_t time_of_compilation;
 
 // Files included by the preprocessor and their hashes. Key: file path. Value:
 // struct digest.
-static struct hashtable *included_files = NULL;
+static struct hashtableincluded_files = NULL;
 
 // Uses absolute path for some include files.
 static bool has_absolute_include_headers = false;
 
 // List of headers to ignore.
-static char **ignore_headers;
+static char** ignore_headers;
 
 // Size of headers to ignore list.
 static size_t ignore_headers_len;
@@ -190,7 +207,7 @@ static bool generating_diagnostics;
 static bool seen_split_dwarf;
 
 // Relocating debuginfo in the format old=new.
-static char **debug_prefix_maps = NULL;
+static char** debug_prefix_maps = NULL;
 
 // Size of debug_prefix_maps list.
 static size_t debug_prefix_maps_len = 0;
@@ -199,23 +216,23 @@ static size_t debug_prefix_maps_len = 0;
 static bool profile_arcs;
 
 // Name of the custom profile directory (default: object dirname).
-static char *profile_dir;
+static charprofile_dir;
 
 // The name of the temporary preprocessed file.
-static char *i_tmpfile;
+static chari_tmpfile;
 
 // Are we compiling a .i or .ii file directly?
 static bool direct_i_file;
 
 // The name of the cpp stderr file.
-static char *cpp_stderr;
+static charcpp_stderr;
 
 // Full path to the statistics file in the subdirectory where the cached result
 // belongs (<cache_dir>/<x>/stats).
-char *stats_file = NULL;
+charstats_file = NULL;
 
 // The stats file to use for the manifest.
-static char *manifest_stats_file;
+static charmanifest_stats_file;
 
 // Whether the output is a precompiled header.
 bool output_is_precompiled_header = false;
@@ -229,7 +246,7 @@ static bool profile_use = false;
 static bool profile_generate = false;
 
 // Sanitize blacklist
-static char **sanitize_blacklists = NULL;
+static char** sanitize_blacklists = NULL;
 
 // Size of sanitize_blacklists
 static size_t sanitize_blacklists_len = 0;
@@ -239,23 +256,21 @@ static size_t sanitize_blacklists_len = 0;
 static bool using_precompiled_header = false;
 
 // The .gch/.pch/.pth file used for compilation.
-static char *included_pch_file = NULL;
+static charincluded_pch_file = NULL;
 
 // How long (in microseconds) to wait before breaking a stale lock.
 unsigned lock_staleness_limit = 2000000;
 
-enum fromcache_call_mode {
-       FROMCACHE_DIRECT_MODE,
-       FROMCACHE_CPP_MODE
-};
+enum fromcache_call_mode { FROMCACHE_DIRECT_MODE, FROMCACHE_CPP_MODE };
 
-struct pending_tmp_file {
-       char *path;
-       struct pending_tmp_file *next;
+struct pending_tmp_file
+{
+  char* path;
+  struct pending_tmp_file* next;
 };
 
 // Temporary files to remove at program exit.
-static struct pending_tmp_file *pending_tmp_files = NULL;
+static struct pending_tmp_filepending_tmp_files = NULL;
 
 #ifndef _WIN32
 static sigset_t fatal_signal_set;
@@ -273,75 +288,73 @@ static pid_t compiler_pid = 0;
 static const char HASH_PREFIX[] = "3";
 
 static void
-add_prefix(struct args *args, char *prefix_command)
+add_prefix(struct args* args, char* prefix_command)
 {
-       if (str_eq(prefix_command, "")) {
-               return;
-       }
-
-       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;
-
-               p = find_executable(tok, MYNAME);
-               if (!p) {
-                       fatal("%s: %s", tok, strerror(errno));
-               }
-
-               args_add(prefix, p);
-               free(p);
-       }
-       free(e);
-
-       cc_log("Using command-line prefix %s", prefix_command);
-       for (int i = prefix->argc; i != 0; i--) {
-               args_add_prefix(args, prefix->argv[i-1]);
-       }
-       args_free(prefix);
+  if (str_eq(prefix_command, "")) {
+    return;
+  }
+
+  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;
+
+    p = find_executable(tok, MYNAME);
+    if (!p) {
+      fatal("%s: %s", tok, strerror(errno));
+    }
+
+    args_add(prefix, p);
+    free(p);
+  }
+  free(e);
+
+  cc_log("Using command-line prefix %s", prefix_command);
+  for (int i = prefix->argc; i != 0; i--) {
+    args_add_prefix(args, prefix->argv[i - 1]);
+  }
+  args_free(prefix);
 }
 
-
 static void failed(void) ATTR_NORETURN;
 
 // Something went badly wrong - just execute the real compiler.
 static void
 failed(void)
 {
-       assert(orig_args);
+  assert(orig_args);
 
-       args_strip(orig_args, "--ccache-");
-       add_prefix(orig_args, conf->prefix_command);
+  args_strip(orig_args, "--ccache-");
+  add_prefix(orig_args, conf->prefix_command);
 
-       cc_log("Failed; falling back to running the real compiler");
-       cc_log_argv("Executing ", orig_args->argv);
-       exitfn_call();
-       execv(orig_args->argv[0], orig_args->argv);
-       fatal("execv of %s failed: %s", orig_args->argv[0], strerror(errno));
+  cc_log("Failed; falling back to running the real compiler");
+  cc_log_argv("Executing ", orig_args->argv);
+  exitfn_call();
+  execv(orig_args->argv[0], orig_args->argv);
+  fatal("execv of %s failed: %s", orig_args->argv[0], strerror(errno));
 }
 
-static const char *
+static const char*
 temp_dir()
 {
-       static char *path = NULL;
-       if (path) {
-               return path; // Memoize
-       }
-       path = conf->temporary_dir;
-       if (str_eq(path, "")) {
-               path = format("%s/tmp", conf->cache_dir);
-       }
-       return path;
+  static char* path = NULL;
+  if (path) {
+    return path; // Memoize
+  }
+  path = conf->temporary_dir;
+  if (str_eq(path, "")) {
+    path = format("%s/tmp", conf->cache_dir);
+  }
+  return path;
 }
 
 void
 block_signals(void)
 {
 #ifndef _WIN32
-       sigprocmask(SIG_BLOCK, &fatal_signal_set, NULL);
+  sigprocmask(SIG_BLOCK, &fatal_signal_set, NULL);
 #endif
 }
 
@@ -349,470 +362,474 @@ void
 unblock_signals(void)
 {
 #ifndef _WIN32
-       sigset_t empty;
-       sigemptyset(&empty);
-       sigprocmask(SIG_SETMASK, &empty, NULL);
+  sigset_t empty;
+  sigemptyset(&empty);
+  sigprocmask(SIG_SETMASK, &empty, NULL);
 #endif
 }
 
 static void
-add_pending_tmp_file(const char *path)
+add_pending_tmp_file(const charpath)
 {
-       block_signals();
-       auto e = static_cast<pending_tmp_file*>(x_malloc(sizeof(pending_tmp_file)));
-       e->path = x_strdup(path);
-       e->next = pending_tmp_files;
-       pending_tmp_files = e;
-       unblock_signals();
+  block_signals();
+  auto e = static_cast<pending_tmp_file*>(x_malloc(sizeof(pending_tmp_file)));
+  e->path = x_strdup(path);
+  e->next = pending_tmp_files;
+  pending_tmp_files = e;
+  unblock_signals();
 }
 
 static void
 do_clean_up_pending_tmp_files(void)
 {
-       struct pending_tmp_file *p = pending_tmp_files;
-       while (p) {
-               // Can't call tmp_unlink here since its cc_log calls aren't signal safe.
-               unlink(p->path);
-               p = p->next;
-               // Leak p->path and p here because clean_up_pending_tmp_files needs to be
-               // signal safe.
-       }
+  struct pending_tmp_file* p = pending_tmp_files;
+  while (p) {
+    // Can't call tmp_unlink here since its cc_log calls aren't signal safe.
+    unlink(p->path);
+    p = p->next;
+    // Leak p->path and p here because clean_up_pending_tmp_files needs to be
+    // signal safe.
+  }
 }
 
 static void
 clean_up_pending_tmp_files(void)
 {
-       block_signals();
-       do_clean_up_pending_tmp_files();
-       unblock_signals();
+  block_signals();
+  do_clean_up_pending_tmp_files();
+  unblock_signals();
 }
 
 #ifndef _WIN32
 static void
 signal_handler(int signum)
 {
-       // Unregister handler for this signal so that we can send the signal to
-       // ourselves at the end of the handler.
-       signal(signum, SIG_DFL);
-
-       // If ccache was killed explicitly, then bring the compiler subprocess (if
-       // any) with us as well.
-       if (signum == SIGTERM
-           && compiler_pid != 0
-           && waitpid(compiler_pid, NULL, WNOHANG) == 0) {
-               kill(compiler_pid, signum);
-       }
-
-       do_clean_up_pending_tmp_files();
-
-       if (compiler_pid != 0) {
-               // Wait for compiler subprocess to exit before we snuff it.
-               waitpid(compiler_pid, NULL, 0);
-       }
-
-       // Resend signal to ourselves to exit properly after returning from the
-       // handler.
-       kill(getpid(), signum);
+  // Unregister handler for this signal so that we can send the signal to
+  // ourselves at the end of the handler.
+  signal(signum, SIG_DFL);
+
+  // If ccache was killed explicitly, then bring the compiler subprocess (if
+  // any) with us as well.
+  if (signum == SIGTERM && compiler_pid != 0
+      && waitpid(compiler_pid, NULL, WNOHANG) == 0) {
+    kill(compiler_pid, signum);
+  }
+
+  do_clean_up_pending_tmp_files();
+
+  if (compiler_pid != 0) {
+    // Wait for compiler subprocess to exit before we snuff it.
+    waitpid(compiler_pid, NULL, 0);
+  }
+
+  // Resend signal to ourselves to exit properly after returning from the
+  // handler.
+  kill(getpid(), signum);
 }
 
 static void
 register_signal_handler(int signum)
 {
-       struct sigaction act;
-       memset(&act, 0, sizeof(act));
-       act.sa_handler = signal_handler;
-       act.sa_mask = fatal_signal_set;
-#ifdef SA_RESTART
-       act.sa_flags = SA_RESTART;
-#endif
-       sigaction(signum, &act, NULL);
+  struct sigaction act;
+  memset(&act, 0, sizeof(act));
+  act.sa_handler = signal_handler;
+  act.sa_mask = fatal_signal_set;
+#  ifdef SA_RESTART
+  act.sa_flags = SA_RESTART;
+#  endif
+  sigaction(signum, &act, NULL);
 }
 
 static void
 set_up_signal_handlers(void)
 {
-       sigemptyset(&fatal_signal_set);
-       sigaddset(&fatal_signal_set, SIGINT);
-       sigaddset(&fatal_signal_set, SIGTERM);
-#ifdef SIGHUP
-       sigaddset(&fatal_signal_set, SIGHUP);
-#endif
-#ifdef SIGQUIT
-       sigaddset(&fatal_signal_set, SIGQUIT);
-#endif
-
-       register_signal_handler(SIGINT);
-       register_signal_handler(SIGTERM);
-#ifdef SIGHUP
-       register_signal_handler(SIGHUP);
-#endif
-#ifdef SIGQUIT
-       register_signal_handler(SIGQUIT);
-#endif
+  sigemptyset(&fatal_signal_set);
+  sigaddset(&fatal_signal_set, SIGINT);
+  sigaddset(&fatal_signal_set, SIGTERM);
+#  ifdef SIGHUP
+  sigaddset(&fatal_signal_set, SIGHUP);
+#  endif
+#  ifdef SIGQUIT
+  sigaddset(&fatal_signal_set, SIGQUIT);
+#  endif
+
+  register_signal_handler(SIGINT);
+  register_signal_handler(SIGTERM);
+#  ifdef SIGHUP
+  register_signal_handler(SIGHUP);
+#  endif
+#  ifdef SIGQUIT
+  register_signal_handler(SIGQUIT);
+#  endif
 }
 #endif // _WIN32
 
 static void
 clean_up_internal_tempdir(void)
 {
-       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 *dir = opendir(temp_dir());
-       if (!dir) {
-               return;
-       }
-
-       struct dirent *entry;
-       while ((entry = readdir(dir))) {
-               if (str_eq(entry->d_name, ".") || str_eq(entry->d_name, "..")) {
-                       continue;
-               }
-
-               char *path = format("%s/%s", temp_dir(), entry->d_name);
-               if (x_lstat(path, &st) == 0 && st.st_mtime + 3600 < now) {
-                       tmp_unlink(path);
-               }
-               free(path);
-       }
-
-       closedir(dir);
+  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* dir = opendir(temp_dir());
+  if (!dir) {
+    return;
+  }
+
+  struct dirent* entry;
+  while ((entry = readdir(dir))) {
+    if (str_eq(entry->d_name, ".") || str_eq(entry->d_name, "..")) {
+      continue;
+    }
+
+    char* path = format("%s/%s", temp_dir(), entry->d_name);
+    if (x_lstat(path, &st) == 0 && st.st_mtime + 3600 < now) {
+      tmp_unlink(path);
+    }
+    free(path);
+  }
+
+  closedir(dir);
 }
 
 static void
-fclose_exitfn(void *context)
+fclose_exitfn(voidcontext)
 {
-       fclose((FILE *)context);
+  fclose((FILE*)context);
 }
 
 static void
-dump_debug_log_buffer_exitfn(void *context)
+dump_debug_log_buffer_exitfn(voidcontext)
 {
-       if (!conf->debug) {
-               return;
-       }
+  if (!conf->debug) {
+    return;
+  }
 
-       char *path = format("%s.ccache-log", (const char *)context);
-       cc_dump_debug_log_buffer(path);
-       free(path);
+  char* path = format("%s.ccache-log", (const char*)context);
+  cc_dump_debug_log_buffer(path);
+  free(path);
 }
 
 static void
-init_hash_debug(struct hash *hash, const char *obj_path, char type,
-                const char *section_name, FILE *debug_text_file)
+init_hash_debug(struct hash* hash,
+                const char* obj_path,
+                char type,
+                const char* section_name,
+                FILE* debug_text_file)
 {
-       if (!conf->debug) {
-               return;
-       }
-
-       char *path = format("%s.ccache-input-%c", obj_path, type);
-       FILE *debug_binary_file = fopen(path, "wb");
-       if (debug_binary_file) {
-               hash_enable_debug(hash, section_name, debug_binary_file, debug_text_file);
-               exitfn_add(fclose_exitfn, debug_binary_file);
-       } else {
-               cc_log("Failed to open %s: %s", path, strerror(errno));
-       }
-       free(path);
+  if (!conf->debug) {
+    return;
+  }
+
+  char* path = format("%s.ccache-input-%c", obj_path, type);
+  FILE* debug_binary_file = fopen(path, "wb");
+  if (debug_binary_file) {
+    hash_enable_debug(hash, section_name, debug_binary_file, debug_text_file);
+    exitfn_add(fclose_exitfn, debug_binary_file);
+  } else {
+    cc_log("Failed to open %s: %s", path, strerror(errno));
+  }
+  free(path);
 }
 
 static enum guessed_compiler
-guess_compiler(const char *path)
+guess_compiler(const charpath)
 {
-       char *name = x_basename(path);
-       enum guessed_compiler result = GUESSED_UNKNOWN;
-       if (strstr(name, "clang")) {
-               result = GUESSED_CLANG;
-       } else if (strstr(name, "gcc") || strstr(name, "g++")) {
-               result = GUESSED_GCC;
-       } else if (strstr(name, "nvcc")) {
-               result = GUESSED_NVCC;
-       } else if (str_eq(name, "pump") || str_eq(name, "distcc-pump")) {
-               result = GUESSED_PUMP;
-       }
-       free(name);
-       return result;
+  char* name = x_basename(path);
+  enum guessed_compiler result = GUESSED_UNKNOWN;
+  if (strstr(name, "clang")) {
+    result = GUESSED_CLANG;
+  } else if (strstr(name, "gcc") || strstr(name, "g++")) {
+    result = GUESSED_GCC;
+  } else if (strstr(name, "nvcc")) {
+    result = GUESSED_NVCC;
+  } else if (str_eq(name, "pump") || str_eq(name, "distcc-pump")) {
+    result = GUESSED_PUMP;
+  }
+  free(name);
+  return result;
 }
 
-static char *
+static char*
 get_current_working_dir(void)
 {
-       if (!current_working_dir) {
-               char *cwd = get_cwd();
-               if (cwd) {
-                       current_working_dir = x_realpath(cwd);
-                       free(cwd);
-               }
-               if (!current_working_dir) {
-                       cc_log("Unable to determine current working directory: %s",
-                              strerror(errno));
-                       failed();
-               }
-       }
-       return current_working_dir;
+  if (!current_working_dir) {
+    char* cwd = get_cwd();
+    if (cwd) {
+      current_working_dir = x_realpath(cwd);
+      free(cwd);
+    }
+    if (!current_working_dir) {
+      cc_log("Unable to determine current working directory: %s",
+             strerror(errno));
+      failed();
+    }
+  }
+  return current_working_dir;
 }
 
 // This function hashes an include file and stores the path and hash in the
 // global included_files variable. If the include file is a PCH, cpp_hash is
 // also updated. Takes over ownership of path.
 static void
-remember_include_file(char *path, struct hash *cpp_hash, bool system,
-                      struct hash *depend_mode_hash)
+remember_include_file(char* path,
+                      struct hash* cpp_hash,
+                      bool system,
+                      struct hash* depend_mode_hash)
 {
-       struct hash *fhash = NULL;
-       bool is_pch = false;
-
-       size_t path_len = strlen(path);
-       if (path_len >= 2 && (path[0] == '<' && path[path_len - 1] == '>')) {
-               // Typically <built-in> or <command-line>.
-               goto out;
-       }
-
-       if (str_eq(path, input_file)) {
-               // Don't remember the input file.
-               goto out;
-       }
-
-       if (system && (conf->sloppiness & SLOPPY_SYSTEM_HEADERS)) {
-               // Don't remember this system header.
-               goto out;
-       }
-
-       if (hashtable_search(included_files, path)) {
-               // Already known include file.
-               goto out;
-       }
+  struct hash* fhash = NULL;
+  bool is_pch = false;
+
+  size_t path_len = strlen(path);
+  if (path_len >= 2 && (path[0] == '<' && path[path_len - 1] == '>')) {
+    // Typically <built-in> or <command-line>.
+    goto out;
+  }
+
+  if (str_eq(path, input_file)) {
+    // Don't remember the input file.
+    goto out;
+  }
+
+  if (system && (conf->sloppiness & SLOPPY_SYSTEM_HEADERS)) {
+    // Don't remember this system header.
+    goto out;
+  }
+
+  if (hashtable_search(included_files, path)) {
+    // Already known include file.
+    goto out;
+  }
 
 #ifdef _WIN32
-       {
-               // stat fails on directories on win32.
-               DWORD attributes = GetFileAttributes(path);
-               if (attributes != INVALID_FILE_ATTRIBUTES &&
-                   attributes & FILE_ATTRIBUTE_DIRECTORY) {
-                       goto out;
-               }
-       }
+  {
+    // stat fails on directories on win32.
+    DWORD attributes = GetFileAttributes(path);
+    if (attributes != INVALID_FILE_ATTRIBUTES
+        && attributes & FILE_ATTRIBUTE_DIRECTORY) {
+      goto out;
+    }
+  }
 #endif
 
-       struct stat st;
-       if (x_stat(path, &st) != 0) {
-               goto failure;
-       }
-       if (S_ISDIR(st.st_mode)) {
-               // Ignore directory, typically $PWD.
-               goto out;
-       }
-       if (!S_ISREG(st.st_mode)) {
-               // Device, pipe, socket or other strange creature.
-               cc_log("Non-regular include file %s", path);
-               goto failure;
-       }
-
-       // Canonicalize path for comparison; clang uses ./header.h.
-       {
-               char *canonical = path;
-               size_t canonical_len = path_len;
-               if (canonical[0] == '.' && canonical[1] == '/') {
-                       canonical += 2;
-                       canonical_len -= 2;
-               }
-
-               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;
-                       }
-                       if (strncmp(canonical, ignore, ignore_len) == 0
-                           && (ignore[ignore_len-1] == DIR_DELIM_CH
-                               || canonical[ignore_len] == DIR_DELIM_CH
-                               || canonical[ignore_len] == '\0')) {
-                               goto out;
-                       }
-               }
-       }
-
-       // The comparison using >= is intentional, due to a possible race between
-       // starting compilation and writing the include file. See also the notes
-       // under "Performance" in doc/MANUAL.adoc.
-       if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_MTIME)
-           && st.st_mtime >= time_of_compilation) {
-               cc_log("Include file %s too new", path);
-               goto failure;
-       }
-
-       // The same >= logic as above applies to the change time of the file.
-       if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_CTIME)
-           && st.st_ctime >= time_of_compilation) {
-               cc_log("Include file %s ctime too new", path);
-               goto failure;
-       }
-
-       // Let's hash the include file content.
-       fhash = hash_init();
-
-       is_pch = is_precompiled_header(path);
-       if (is_pch) {
-               if (!included_pch_file) {
-                       cc_log("Detected use of precompiled header: %s", path);
-               }
-               bool using_pch_sum = false;
-               if (conf->pch_external_checksum) {
-                       // hash pch.sum instead of pch when it exists
-                       // to prevent hashing a very large .pch file every time
-                       char *pch_sum_path = format("%s.sum", path);
-                       if (x_stat(pch_sum_path, &st) == 0) {
-                               char *old_path = path;
-                               path = pch_sum_path;
-                               pch_sum_path = old_path;
-                               using_pch_sum = true;
-                               cc_log("Using pch.sum file %s", path);
-                       }
-                       free(pch_sum_path);
-               }
-
-               if (!hash_file(fhash, path)) {
-                       goto failure;
-               }
-               hash_delimiter(cpp_hash, using_pch_sum ? "pch_sum_hash" : "pch_hash");
-               char pch_digest[DIGEST_STRING_BUFFER_SIZE];
-               hash_result_as_string(fhash, pch_digest);
-               hash_string(cpp_hash, pch_digest);
-       }
-
-       if (conf->direct_mode) {
-               if (!is_pch) { // else: the file has already been hashed.
-                       char *source = NULL;
-                       size_t size;
-                       if (st.st_size > 0) {
-                               if (!read_file(path, st.st_size, &source, &size)) {
-                                       goto failure;
-                               }
-                       } else {
-                               source = x_strdup("");
-                               size = 0;
-                       }
-
-                       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;
-                       }
-               }
-
-               auto d = static_cast<digest*>(x_malloc(sizeof(digest)));
-               hash_result_as_bytes(fhash, d);
-               hashtable_insert(included_files, path, d);
-               path = NULL; // Ownership transferred to included_files.
-
-               if (depend_mode_hash) {
-                       hash_delimiter(depend_mode_hash, "include");
-                       char digest[DIGEST_STRING_BUFFER_SIZE];
-                       digest_as_string(d, digest);
-                       hash_string(depend_mode_hash, digest);
-               }
-       }
-
-       goto out;
+  struct stat st;
+  if (x_stat(path, &st) != 0) {
+    goto failure;
+  }
+  if (S_ISDIR(st.st_mode)) {
+    // Ignore directory, typically $PWD.
+    goto out;
+  }
+  if (!S_ISREG(st.st_mode)) {
+    // Device, pipe, socket or other strange creature.
+    cc_log("Non-regular include file %s", path);
+    goto failure;
+  }
+
+  // Canonicalize path for comparison; clang uses ./header.h.
+  {
+    char* canonical = path;
+    size_t canonical_len = path_len;
+    if (canonical[0] == '.' && canonical[1] == '/') {
+      canonical += 2;
+      canonical_len -= 2;
+    }
+
+    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;
+      }
+      if (strncmp(canonical, ignore, ignore_len) == 0
+          && (ignore[ignore_len - 1] == DIR_DELIM_CH
+              || canonical[ignore_len] == DIR_DELIM_CH
+              || canonical[ignore_len] == '\0')) {
+        goto out;
+      }
+    }
+  }
+
+  // The comparison using >= is intentional, due to a possible race between
+  // starting compilation and writing the include file. See also the notes
+  // under "Performance" in doc/MANUAL.adoc.
+  if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_MTIME)
+      && st.st_mtime >= time_of_compilation) {
+    cc_log("Include file %s too new", path);
+    goto failure;
+  }
+
+  // The same >= logic as above applies to the change time of the file.
+  if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_CTIME)
+      && st.st_ctime >= time_of_compilation) {
+    cc_log("Include file %s ctime too new", path);
+    goto failure;
+  }
+
+  // Let's hash the include file content.
+  fhash = hash_init();
+
+  is_pch = is_precompiled_header(path);
+  if (is_pch) {
+    if (!included_pch_file) {
+      cc_log("Detected use of precompiled header: %s", path);
+    }
+    bool using_pch_sum = false;
+    if (conf->pch_external_checksum) {
+      // hash pch.sum instead of pch when it exists
+      // to prevent hashing a very large .pch file every time
+      char* pch_sum_path = format("%s.sum", path);
+      if (x_stat(pch_sum_path, &st) == 0) {
+        char* old_path = path;
+        path = pch_sum_path;
+        pch_sum_path = old_path;
+        using_pch_sum = true;
+        cc_log("Using pch.sum file %s", path);
+      }
+      free(pch_sum_path);
+    }
+
+    if (!hash_file(fhash, path)) {
+      goto failure;
+    }
+    hash_delimiter(cpp_hash, using_pch_sum ? "pch_sum_hash" : "pch_hash");
+    char pch_digest[DIGEST_STRING_BUFFER_SIZE];
+    hash_result_as_string(fhash, pch_digest);
+    hash_string(cpp_hash, pch_digest);
+  }
+
+  if (conf->direct_mode) {
+    if (!is_pch) { // else: the file has already been hashed.
+      char* source = NULL;
+      size_t size;
+      if (st.st_size > 0) {
+        if (!read_file(path, st.st_size, &source, &size)) {
+          goto failure;
+        }
+      } else {
+        source = x_strdup("");
+        size = 0;
+      }
+
+      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;
+      }
+    }
+
+    auto d = static_cast<digest*>(x_malloc(sizeof(digest)));
+    hash_result_as_bytes(fhash, d);
+    hashtable_insert(included_files, path, d);
+    path = NULL; // Ownership transferred to included_files.
+
+    if (depend_mode_hash) {
+      hash_delimiter(depend_mode_hash, "include");
+      char digest[DIGEST_STRING_BUFFER_SIZE];
+      digest_as_string(d, digest);
+      hash_string(depend_mode_hash, digest);
+    }
+  }
+
+  goto out;
 
 failure:
-       if (conf->direct_mode) {
-               cc_log("Disabling direct mode");
-               conf->direct_mode = false;
-       }
-       // Fall through.
+  if (conf->direct_mode) {
+    cc_log("Disabling direct mode");
+    conf->direct_mode = false;
+  }
+  // Fall through.
 out:
-       hash_free(fhash);
-       free(path);
+  hash_free(fhash);
+  free(path);
 }
 
 static void
-print_included_files(FILE *fp)
+print_included_files(FILEfp)
 {
-       struct hashtable_itr *iter = hashtable_iterator(included_files);
-       do {
-               char* path = static_cast<char*>(hashtable_iterator_key(iter));
-               fprintf(fp, "%s\n", path);
-       } while (hashtable_iterator_advance(iter));
+  struct hashtable_itr* iter = hashtable_iterator(included_files);
+  do {
+    char* path = static_cast<char*>(hashtable_iterator_key(iter));
+    fprintf(fp, "%s\n", path);
+  } while (hashtable_iterator_advance(iter));
 }
 
 // Make a relative path from current working directory to path if path is under
 // the base directory. Takes over ownership of path. Caller frees.
-static char *
-make_relative_path(char *path)
+static char*
+make_relative_path(charpath)
 {
-       if (str_eq(conf->base_dir, "") || !str_startswith(path, conf->base_dir)) {
-               return path;
-       }
+  if (str_eq(conf->base_dir, "") || !str_startswith(path, conf->base_dir)) {
+    return path;
+  }
 
 #ifdef _WIN32
-       if (path[0] == '/') {
-               path++;  // Skip leading slash.
-       }
+  if (path[0] == '/') {
+    path++; // Skip leading slash.
+  }
 #endif
 
-       // x_realpath only works for existing paths, so if path doesn't exist, try
-       // x_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 x_dirname(path) exists.
-       char *path_suffix = NULL;
-       struct stat st;
-       if (stat(path, &st) != 0) {
-               // path doesn't exist.
-               char *dir = x_dirname(path);
-               // find the nearest existing directory in path
-               while (stat(dir, &st) != 0) {
-                       char *parent_dir = x_dirname(dir);
-                       free(dir);
-                       dir = parent_dir;
-               }
-
-               // suffix is the remaining of the path, skip the first delimiter
-               size_t dir_len = strlen(dir);
-               if (path[dir_len] == '/' || path[dir_len] == '\\') {
-                       dir_len++;
-               }
-               path_suffix = x_strdup(&path[dir_len]);
-               char *p = path;
-               path = dir;
-               free(p);
-       }
-
-       char *canon_path = x_realpath(path);
-       if (canon_path) {
-               free(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);
-                       free(relpath);
-                       free(path_suffix);
-                       return path;
-               } else {
-                       return relpath;
-               }
-       } else {
-               // path doesn't exist, so leave it as it is.
-               free(path_suffix);
-               return path;
-       }
+  // x_realpath only works for existing paths, so if path doesn't exist, try
+  // x_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 x_dirname(path) exists.
+  char* path_suffix = NULL;
+  struct stat st;
+  if (stat(path, &st) != 0) {
+    // path doesn't exist.
+    char* dir = x_dirname(path);
+    // find the nearest existing directory in path
+    while (stat(dir, &st) != 0) {
+      char* parent_dir = x_dirname(dir);
+      free(dir);
+      dir = parent_dir;
+    }
+
+    // suffix is the remaining of the path, skip the first delimiter
+    size_t dir_len = strlen(dir);
+    if (path[dir_len] == '/' || path[dir_len] == '\\') {
+      dir_len++;
+    }
+    path_suffix = x_strdup(&path[dir_len]);
+    char* p = path;
+    path = dir;
+    free(p);
+  }
+
+  char* canon_path = x_realpath(path);
+  if (canon_path) {
+    free(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);
+      free(relpath);
+      free(path_suffix);
+      return path;
+    } else {
+      return relpath;
+    }
+  } else {
+    // path doesn't exist, so leave it as it is.
+    free(path_suffix);
+    return path;
+  }
 }
 
 static void
 init_included_files_table(void)
 {
-       // (This function may be called multiple times if several -arch options are
-       // used.)
-       if (!included_files) {
-               included_files = create_hashtable(1000, hash_from_string, strings_equal);
-       }
+  // (This function may be called multiple times if several -arch options are
+  // used.)
+  if (!included_files) {
+    included_files = create_hashtable(1000, hash_from_string, strings_equal);
+  }
 }
 
 // This function reads and hashes a file. While doing this, it also does these
@@ -823,779 +840,788 @@ init_included_files_table(void)
 // - Stores the paths and hashes of included files in the global variable
 //   included_files.
 static bool
-process_preprocessed_file(struct hash *hash, const char *path, bool pump)
+process_preprocessed_file(struct hash* hash, const char* path, bool pump)
 {
-       char *data;
-       size_t size;
-       if (!read_file(path, 0, &data, &size)) {
-               return false;
-       }
-
-       ignore_headers = NULL;
-       ignore_headers_len = 0;
-       if (!str_eq(conf->ignore_headers_in_manifest, "")) {
-               char *header, *p, *q, *saveptr = NULL;
-               p = x_strdup(conf->ignore_headers_in_manifest);
-               q = p;
-               while ((header = strtok_r(q, PATH_DELIM, &saveptr))) {
-                       ignore_headers = static_cast<char**>(
-                               x_realloc(ignore_headers, (ignore_headers_len+1) * sizeof(char *)));
-                       ignore_headers[ignore_headers_len++] = x_strdup(header);
-                       q = NULL;
-               }
-               free(p);
-       }
-
-       init_included_files_table();
-
-       char *cwd = gnu_getcwd();
-
-       // Bytes between p and q are pending to be hashed.
-       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) {
-               // Check if we look at a line containing the file name of an included file.
-               // At least the following formats exist (where N is a positive integer):
-               //
-               // GCC:
-               //
-               //   # N "file"
-               //   # N "file" N
-               //   #pragma GCC pch_preprocess "file"
-               //
-               // HP's compiler:
-               //
-               //   #line N "file"
-               //
-               // AIX's compiler:
-               //
-               //   #line N "file"
-               //   #line N
-               //
-               // Note that there may be other lines starting with '#' left after
-               // preprocessing as well, for instance "#    pragma".
-               if (q[0] == '#'
-                   // GCC:
-                   && ((q[1] == ' ' && q[2] >= '0' && q[2] <= '9')
-                       // GCC precompiled header:
-                       || (q[1] == 'p'
-                           && str_startswith(&q[2], "ragma GCC pch_preprocess "))
-                       // HP/AIX:
-                       || (q[1] == 'l' && q[2] == 'i' && q[3] == 'n' && q[4] == 'e'
-                           && q[5] == ' '))
-                   && (q == data || q[-1] == '\n')) {
-                       // Workarounds for preprocessor linemarker bugs in GCC version 6.
-                       if (q[2] == '3') {
-                               if (str_startswith(q, "# 31 \"<command-line>\"\n")) {
-                                       // Bogus extra line with #31, after the regular #1: Ignore the whole
-                                       // line, and continue parsing.
-                                       hash_string_buffer(hash, p, q - p);
-                                       while (q < end && *q != '\n') {
-                                               q++;
-                                       }
-                                       q++;
-                                       p = q;
-                                       continue;
-                               } else if (str_startswith(q, "# 32 \"<command-line>\" 2\n")) {
-                                       // Bogus wrong line with #32, instead of regular #1: Replace the line
-                                       // number with the usual one.
-                                       hash_string_buffer(hash, p, q - p);
-                                       q += 1;
-                                       q[0] = '#';
-                                       q[1] = ' ';
-                                       q[2] = '1';
-                                       p = q;
-                               }
-                       }
-
-                       while (q < end && *q != '"' && *q != '\n') {
-                               q++;
-                       }
-                       if (q < end && *q == '\n') {
-                               // A newline before the quotation mark -> no match.
-                               continue;
-                       }
-                       q++;
-                       if (q >= end) {
-                               cc_log("Failed to parse included file path");
-                               free(data);
-                               free(cwd);
-                               return false;
-                       }
-                       // q points to the beginning of an include file path
-                       hash_string_buffer(hash, p, q - p);
-                       p = q;
-                       while (q < end && *q != '"') {
-                               q++;
-                       }
-                       // Look for preprocessor flags, after the "filename".
-                       bool system = false;
-                       char *r = q + 1;
-                       while (r < end && *r != '\n') {
-                               if (*r == '3') { // System header.
-                                       system = true;
-                               }
-                               r++;
-                       }
-                       // p and q span the include file path.
-                       char *inc_path = x_strndup(p, q - p);
-                       if (!has_absolute_include_headers) {
-                               has_absolute_include_headers = is_absolute_path(inc_path);
-                       }
-                       inc_path = make_relative_path(inc_path);
-
-                       bool should_hash_inc_path = true;
-                       if (!conf->hash_dir) {
-                               if (str_startswith(inc_path, cwd) && str_endswith(inc_path, "//")) {
-                                       // When compiling with -g or similar, GCC adds the absolute path to
-                                       // CWD like this:
-                                       //
-                                       //   # 1 "CWD//"
-                                       //
-                                       // If the user has opted out of including the CWD in the hash, don't
-                                       // hash it. See also how debug_prefix_map is handled.
-                                       should_hash_inc_path = false;
-                               }
-                       }
-                       if (should_hash_inc_path) {
-                               hash_string_buffer(hash, inc_path, strlen(inc_path));
-                       }
-
-                       remember_include_file(inc_path, hash, system, NULL);
-                       p = q; // Everything of interest between p and q has been hashed now.
-               } else if (q[0] == '.' && q[1] == 'i' && q[2] == 'n' && q[3] == 'c'
-                          && q[4] == 'b' && q[5] == 'i' && q[6] == 'n') {
-                       // An assembler .inc bin (without the space) statement, which could be
-                       // part of inline assembly, refers to an external file. If the file
-                       // changes, the hash should change as well, but finding out what file to
-                       // hash is too hard for ccache, so just bail out.
-                       cc_log("Found unsupported .inc" "bin directive in source code");
-                       stats_update(STATS_UNSUPPORTED_DIRECTIVE);
-                       failed();
-               } else if (pump && strncmp(q, "_________", 9) == 0) {
-                       // Unfortunately the distcc-pump wrapper outputs standard output lines:
-                       // __________Using distcc-pump from /usr/bin
-                       // __________Using # distcc servers in pump mode
-                       // __________Shutting down distcc-pump include server
-                       while (q < end && *q != '\n') {
-                               q++;
-                       }
-                       if (*q == '\n') {
-                               q++;
-                       }
-                       p = q;
-                       continue;
-               } else {
-                       q++;
-               }
-       }
-
-       hash_string_buffer(hash, p, (end - p));
-       free(data);
-       free(cwd);
-
-       // Explicitly check the .gch/.pch/.pth file as Clang does not include any
-       // mention of it in the preprocessed output.
-       if (included_pch_file) {
-               char *pch_path = x_strdup(included_pch_file);
-               pch_path = make_relative_path(pch_path);
-               hash_string(hash, pch_path);
-               remember_include_file(pch_path, hash, false, NULL);
-       }
-
-       bool debug_included = getenv("CCACHE_DEBUG_INCLUDED");
-       if (debug_included) {
-               print_included_files(stdout);
-       }
-
-       return true;
+  char* data;
+  size_t size;
+  if (!read_file(path, 0, &data, &size)) {
+    return false;
+  }
+
+  ignore_headers = NULL;
+  ignore_headers_len = 0;
+  if (!str_eq(conf->ignore_headers_in_manifest, "")) {
+    char *header, *p, *q, *saveptr = NULL;
+    p = x_strdup(conf->ignore_headers_in_manifest);
+    q = p;
+    while ((header = strtok_r(q, PATH_DELIM, &saveptr))) {
+      ignore_headers = static_cast<char**>(
+        x_realloc(ignore_headers, (ignore_headers_len + 1) * sizeof(char*)));
+      ignore_headers[ignore_headers_len++] = x_strdup(header);
+      q = NULL;
+    }
+    free(p);
+  }
+
+  init_included_files_table();
+
+  char* cwd = gnu_getcwd();
+
+  // Bytes between p and q are pending to be hashed.
+  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) {
+    // Check if we look at a line containing the file name of an included file.
+    // At least the following formats exist (where N is a positive integer):
+    //
+    // GCC:
+    //
+    //   # N "file"
+    //   # N "file" N
+    //   #pragma GCC pch_preprocess "file"
+    //
+    // HP's compiler:
+    //
+    //   #line N "file"
+    //
+    // AIX's compiler:
+    //
+    //   #line N "file"
+    //   #line N
+    //
+    // Note that there may be other lines starting with '#' left after
+    // preprocessing as well, for instance "#    pragma".
+    if (q[0] == '#'
+        // GCC:
+        && ((q[1] == ' ' && q[2] >= '0' && q[2] <= '9')
+            // GCC precompiled header:
+            || (q[1] == 'p'
+                && str_startswith(&q[2], "ragma GCC pch_preprocess "))
+            // HP/AIX:
+            || (q[1] == 'l' && q[2] == 'i' && q[3] == 'n' && q[4] == 'e'
+                && q[5] == ' '))
+        && (q == data || q[-1] == '\n')) {
+      // Workarounds for preprocessor linemarker bugs in GCC version 6.
+      if (q[2] == '3') {
+        if (str_startswith(q, "# 31 \"<command-line>\"\n")) {
+          // Bogus extra line with #31, after the regular #1: Ignore the whole
+          // line, and continue parsing.
+          hash_string_buffer(hash, p, q - p);
+          while (q < end && *q != '\n') {
+            q++;
+          }
+          q++;
+          p = q;
+          continue;
+        } else if (str_startswith(q, "# 32 \"<command-line>\" 2\n")) {
+          // Bogus wrong line with #32, instead of regular #1: Replace the line
+          // number with the usual one.
+          hash_string_buffer(hash, p, q - p);
+          q += 1;
+          q[0] = '#';
+          q[1] = ' ';
+          q[2] = '1';
+          p = q;
+        }
+      }
+
+      while (q < end && *q != '"' && *q != '\n') {
+        q++;
+      }
+      if (q < end && *q == '\n') {
+        // A newline before the quotation mark -> no match.
+        continue;
+      }
+      q++;
+      if (q >= end) {
+        cc_log("Failed to parse included file path");
+        free(data);
+        free(cwd);
+        return false;
+      }
+      // q points to the beginning of an include file path
+      hash_string_buffer(hash, p, q - p);
+      p = q;
+      while (q < end && *q != '"') {
+        q++;
+      }
+      // Look for preprocessor flags, after the "filename".
+      bool system = false;
+      char* r = q + 1;
+      while (r < end && *r != '\n') {
+        if (*r == '3') { // System header.
+          system = true;
+        }
+        r++;
+      }
+      // p and q span the include file path.
+      char* inc_path = x_strndup(p, q - p);
+      if (!has_absolute_include_headers) {
+        has_absolute_include_headers = is_absolute_path(inc_path);
+      }
+      inc_path = make_relative_path(inc_path);
+
+      bool should_hash_inc_path = true;
+      if (!conf->hash_dir) {
+        if (str_startswith(inc_path, cwd) && str_endswith(inc_path, "//")) {
+          // When compiling with -g or similar, GCC adds the absolute path to
+          // CWD like this:
+          //
+          //   # 1 "CWD//"
+          //
+          // If the user has opted out of including the CWD in the hash, don't
+          // hash it. See also how debug_prefix_map is handled.
+          should_hash_inc_path = false;
+        }
+      }
+      if (should_hash_inc_path) {
+        hash_string_buffer(hash, inc_path, strlen(inc_path));
+      }
+
+      remember_include_file(inc_path, hash, system, NULL);
+      p = q; // Everything of interest between p and q has been hashed now.
+    } else if (q[0] == '.' && q[1] == 'i' && q[2] == 'n' && q[3] == 'c'
+               && q[4] == 'b' && q[5] == 'i' && q[6] == 'n') {
+      // An assembler .inc bin (without the space) statement, which could be
+      // part of inline assembly, refers to an external file. If the file
+      // changes, the hash should change as well, but finding out what file to
+      // hash is too hard for ccache, so just bail out.
+      cc_log(
+        "Found unsupported .inc"
+        "bin directive in source code");
+      stats_update(STATS_UNSUPPORTED_DIRECTIVE);
+      failed();
+    } else if (pump && strncmp(q, "_________", 9) == 0) {
+      // Unfortunately the distcc-pump wrapper outputs standard output lines:
+      // __________Using distcc-pump from /usr/bin
+      // __________Using # distcc servers in pump mode
+      // __________Shutting down distcc-pump include server
+      while (q < end && *q != '\n') {
+        q++;
+      }
+      if (*q == '\n') {
+        q++;
+      }
+      p = q;
+      continue;
+    } else {
+      q++;
+    }
+  }
+
+  hash_string_buffer(hash, p, (end - p));
+  free(data);
+  free(cwd);
+
+  // Explicitly check the .gch/.pch/.pth file as Clang does not include any
+  // mention of it in the preprocessed output.
+  if (included_pch_file) {
+    char* pch_path = x_strdup(included_pch_file);
+    pch_path = make_relative_path(pch_path);
+    hash_string(hash, pch_path);
+    remember_include_file(pch_path, hash, false, NULL);
+  }
+
+  bool debug_included = getenv("CCACHE_DEBUG_INCLUDED");
+  if (debug_included) {
+    print_included_files(stdout);
+  }
+
+  return true;
 }
 
 // Replace absolute paths with relative paths in the provided dependency file.
 static void
-use_relative_paths_in_depfile(const char *depfile)
+use_relative_paths_in_depfile(const chardepfile)
 {
-       if (str_eq(conf->base_dir, "")) {
-               cc_log("Base dir not set, skip using relative paths");
-               return; // nothing to do
-       }
-       if (!has_absolute_include_headers) {
-               cc_log("No absolute path for included files found, skip using relative"
-                      " paths");
-               return; // nothing to do
-       }
-
-       FILE *f;
-       f = fopen(depfile, "r");
-       if (!f) {
-               cc_log("Cannot open dependency file: %s (%s)", depfile, strerror(errno));
-               return;
-       }
-
-       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)) {
-               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.
-                               fputc(' ', tmpf);
-                       }
-                       fputs(relpath, tmpf);
-                       if (relpath != token) {
-                               free(relpath);
-                       }
-                       token = strtok_r(NULL, " \t", &saveptr);
-               }
-       }
-
-       if (ferror(f)) {
-               cc_log("Error reading dependency file: %s, skip relative path usage",
-                      depfile);
-               result = false;
-               goto out;
-       }
-       if (ferror(tmpf)) {
-               cc_log("Error writing temporary dependency file: %s, skip relative path"
-                      " usage", tmp_file);
-               result = false;
-               goto out;
-       }
+  if (str_eq(conf->base_dir, "")) {
+    cc_log("Base dir not set, skip using relative paths");
+    return; // nothing to do
+  }
+  if (!has_absolute_include_headers) {
+    cc_log(
+      "No absolute path for included files found, skip using relative"
+      " paths");
+    return; // nothing to do
+  }
+
+  FILE* f;
+  f = fopen(depfile, "r");
+  if (!f) {
+    cc_log("Cannot open dependency file: %s (%s)", depfile, strerror(errno));
+    return;
+  }
+
+  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)) {
+    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.
+        fputc(' ', tmpf);
+      }
+      fputs(relpath, tmpf);
+      if (relpath != token) {
+        free(relpath);
+      }
+      token = strtok_r(NULL, " \t", &saveptr);
+    }
+  }
+
+  if (ferror(f)) {
+    cc_log("Error reading dependency file: %s, skip relative path usage",
+           depfile);
+    result = false;
+    goto out;
+  }
+  if (ferror(tmpf)) {
+    cc_log(
+      "Error writing temporary dependency file: %s, skip relative path"
+      " usage",
+      tmp_file);
+    result = false;
+    goto out;
+  }
 
 out:
-       fclose(tmpf);
-       fclose(f);
-       if (result) {
-               if (x_rename(tmp_file, depfile) != 0) {
-                       cc_log("Error renaming dependency file: %s -> %s (%s), skip relative"
-                              " path usage", tmp_file, depfile, strerror(errno));
-                       result = false;
-               } else {
-                       cc_log("Renamed dependency file: %s -> %s", tmp_file, depfile);
-               }
-       }
-       if (!result) {
-               cc_log("Removing temporary dependency file: %s", tmp_file);
-               x_unlink(tmp_file);
-       }
-       free(tmp_file);
+  fclose(tmpf);
+  fclose(f);
+  if (result) {
+    if (x_rename(tmp_file, depfile) != 0) {
+      cc_log(
+        "Error renaming dependency file: %s -> %s (%s), skip relative"
+        " path usage",
+        tmp_file,
+        depfile,
+        strerror(errno));
+      result = false;
+    } else {
+      cc_log("Renamed dependency file: %s -> %s", tmp_file, depfile);
+    }
+  }
+  if (!result) {
+    cc_log("Removing temporary dependency file: %s", tmp_file);
+    x_unlink(tmp_file);
+  }
+  free(tmp_file);
 }
 
 // Extract the used includes from the dependency file. Note that we cannot
 // distinguish system headers from other includes here.
-static struct digest *
-result_name_from_depfile(const char *depfile, struct hash *hash)
+static struct digest*
+result_name_from_depfile(const char* depfile, struct hash* hash)
 {
-       FILE *f = fopen(depfile, "r");
-       if (!f) {
-               cc_log("Cannot open dependency file %s: %s", depfile, strerror(errno));
-               return NULL;
-       }
-
-       init_included_files_table();
-
-       char buf[10000];
-       while (fgets(buf, sizeof(buf), f) && !ferror(f)) {
-               char *saveptr;
-               char *token;
-               for (token = strtok_r(buf, " \t\n", &saveptr);
-                    token;
-                    token = strtok_r(NULL, " \t\n", &saveptr)) {
-                       if (str_endswith(token, ":") || str_eq(token, "\\")) {
-                               continue;
-                       }
-                       if (!has_absolute_include_headers) {
-                               has_absolute_include_headers = is_absolute_path(token);
-                       }
-                       char *path = make_relative_path(x_strdup(token));
-                       remember_include_file(path, hash, false, hash);
-               }
-       }
-
-       fclose(f);
-
-       // Explicitly check the .gch/.pch/.pth file as it may not be mentioned in the
-       // dependencies output.
-       if (included_pch_file) {
-               char *pch_path = x_strdup(included_pch_file);
-               pch_path = make_relative_path(pch_path);
-               hash_string(hash, pch_path);
-               remember_include_file(pch_path, hash, false, NULL);
-       }
-
-       bool debug_included = getenv("CCACHE_DEBUG_INCLUDED");
-       if (debug_included) {
-               print_included_files(stdout);
-       }
-
-       auto d = static_cast<digest*>(x_malloc(sizeof(digest)));
-       hash_result_as_bytes(hash, d);
-       return d;
+  FILE* f = fopen(depfile, "r");
+  if (!f) {
+    cc_log("Cannot open dependency file %s: %s", depfile, strerror(errno));
+    return NULL;
+  }
+
+  init_included_files_table();
+
+  char buf[10000];
+  while (fgets(buf, sizeof(buf), f) && !ferror(f)) {
+    char* saveptr;
+    char* token;
+    for (token = strtok_r(buf, " \t\n", &saveptr); token;
+         token = strtok_r(NULL, " \t\n", &saveptr)) {
+      if (str_endswith(token, ":") || str_eq(token, "\\")) {
+        continue;
+      }
+      if (!has_absolute_include_headers) {
+        has_absolute_include_headers = is_absolute_path(token);
+      }
+      char* path = make_relative_path(x_strdup(token));
+      remember_include_file(path, hash, false, hash);
+    }
+  }
+
+  fclose(f);
+
+  // Explicitly check the .gch/.pch/.pth file as it may not be mentioned in the
+  // dependencies output.
+  if (included_pch_file) {
+    char* pch_path = x_strdup(included_pch_file);
+    pch_path = make_relative_path(pch_path);
+    hash_string(hash, pch_path);
+    remember_include_file(pch_path, hash, false, NULL);
+  }
+
+  bool debug_included = getenv("CCACHE_DEBUG_INCLUDED");
+  if (debug_included) {
+    print_included_files(stdout);
+  }
+
+  auto d = static_cast<digest*>(x_malloc(sizeof(digest)));
+  hash_result_as_bytes(hash, d);
+  return d;
 }
 
 // Send cached stderr, if any, to stderr.
 static void
-send_cached_stderr(const char *path_stderr)
+send_cached_stderr(const charpath_stderr)
 {
-       int fd_stderr = open(path_stderr, O_RDONLY | O_BINARY);
-       if (fd_stderr != -1) {
-               copy_fd(fd_stderr, 2);
-               close(fd_stderr);
-       }
+  int fd_stderr = open(path_stderr, O_RDONLY | O_BINARY);
+  if (fd_stderr != -1) {
+    copy_fd(fd_stderr, 2);
+    close(fd_stderr);
+  }
 }
 
 // Create or update the manifest file.
 static void
 update_manifest_file(void)
 {
-       if (!conf->direct_mode
-           || !included_files
-           || conf->read_only
-           || conf->read_only_direct) {
-               return;
-       }
-
-       struct stat st;
-       size_t old_size = 0; // in bytes
-       if (stat(manifest_path, &st) == 0) {
-               old_size = file_size(&st);
-       }
-
-       MTR_BEGIN("manifest", "manifest_put");
-       cc_log("Adding result name to %s", manifest_path);
-       if (manifest_put(manifest_path, cached_result_name, included_files)) {
-               if (x_stat(manifest_path, &st) == 0) {
-                       stats_update_size(
-                               manifest_stats_file,
-                               file_size(&st) - old_size,
-                               old_size == 0 ? 1 : 0);
-               }
-       } else {
-               cc_log("Failed to add result name to %s", manifest_path);
-       }
-       MTR_END("manifest", "manifest_put");
+  if (!conf->direct_mode || !included_files || conf->read_only
+      || conf->read_only_direct) {
+    return;
+  }
+
+  struct stat st;
+  size_t old_size = 0; // in bytes
+  if (stat(manifest_path, &st) == 0) {
+    old_size = file_size(&st);
+  }
+
+  MTR_BEGIN("manifest", "manifest_put");
+  cc_log("Adding result name to %s", manifest_path);
+  if (manifest_put(manifest_path, cached_result_name, included_files)) {
+    if (x_stat(manifest_path, &st) == 0) {
+      stats_update_size(
+        manifest_stats_file, file_size(&st) - old_size, old_size == 0 ? 1 : 0);
+    }
+  } else {
+    cc_log("Failed to add result name to %s", manifest_path);
+  }
+  MTR_END("manifest", "manifest_put");
 }
 
 static void
-update_cached_result_globals(struct digest *result_name)
+update_cached_result_globals(struct digestresult_name)
 {
-       char result_name_string[DIGEST_STRING_BUFFER_SIZE];
-       digest_as_string(result_name, result_name_string);
-       cached_result_name = result_name;
-       cached_result_path = get_path_in_cache(result_name_string, ".result");
-       stats_file = format("%s/%c/stats", conf->cache_dir, result_name_string[0]);
+  char result_name_string[DIGEST_STRING_BUFFER_SIZE];
+  digest_as_string(result_name, result_name_string);
+  cached_result_name = result_name;
+  cached_result_path = get_path_in_cache(result_name_string, ".result");
+  stats_file = format("%s/%c/stats", conf->cache_dir, result_name_string[0]);
 }
 
 // Run the real compiler and put the result in cache.
 static void
-to_cache(struct args *args, struct hash *depend_mode_hash)
+to_cache(struct args* args, struct hash* depend_mode_hash)
 {
-       args_add(args, "-o");
-       args_add(args, output_obj);
-
-       if (conf->hard_link) {
-               // Workaround for Clang bug where it overwrites an existing object file
-               // when it's compiling an assembler file, see
-               // <https://bugs.llvm.org/show_bug.cgi?id=39782>.
-               x_unlink(output_obj);
-       }
-
-       if (generating_diagnostics) {
-               args_add(args, "--serialize-diagnostics");
-               args_add(args, output_dia);
-       }
-
-       // Turn off DEPENDENCIES_OUTPUT when running cc1, because otherwise it will
-       // emit a line like this:
-       //
-       //   tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i
-       x_unsetenv("DEPENDENCIES_OUTPUT");
-       x_unsetenv("SUNPRO_DEPENDENCIES");
-
-       if (conf->run_second_cpp) {
-               args_add(args, input_file);
-       } else {
-               args_add(args, i_tmpfile);
-       }
-
-       if (seen_split_dwarf) {
-               // Remove any pre-existing .dwo file since we want to check if the compiler
-               // produced one, intentionally not using x_unlink or tmp_unlink since we're
-               // not interested in logging successful deletions or failures due to
-               // non-existent .dwo files.
-               if (unlink(output_dwo) == -1 && errno != ENOENT) {
-                       cc_log("Failed to unlink %s: %s", output_dwo, strerror(errno));
-                       stats_update(STATS_BADOUTPUTFILE);
-               }
-       }
-
-       cc_log("Running real compiler");
-       MTR_BEGIN("execute", "compiler");
-       char *tmp_stdout;
-       int tmp_stdout_fd;
-       char *tmp_stderr;
-       int tmp_stderr_fd;
-       int status;
-       if (!conf->depend_mode) {
-               tmp_stdout = format("%s/tmp.stdout", temp_dir());
-               tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
-               tmp_stderr = format("%s/tmp.stderr", temp_dir());
-               tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
-               status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
-               args_pop(args, 3);
-       } else {
-               // The cached result path is not known yet, use temporary files.
-               tmp_stdout = format("%s/tmp.stdout", temp_dir());
-               tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
-               tmp_stderr = format("%s/tmp.stderr", temp_dir());
-               tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
-
-               // Use the original arguments (including dependency options) in depend
-               // mode.
-               assert(orig_args);
-               struct args *depend_mode_args = args_copy(orig_args);
-               args_strip(depend_mode_args, "--ccache-");
-               add_prefix(depend_mode_args, conf->prefix_command);
-
-               time_of_compilation = time(NULL);
-               status = execute(
-                       depend_mode_args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
-               args_free(depend_mode_args);
-       }
-       MTR_END("execute", "compiler");
-
-       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);
-               tmp_unlink(tmp_stdout);
-               tmp_unlink(tmp_stderr);
-               failed();
-       }
-
-       // distcc-pump outputs lines like this:
-       // __________Using # distcc servers in pump mode
-       if (st.st_size != 0 && guessed_compiler != GUESSED_PUMP) {
-               cc_log("Compiler produced stdout");
-               stats_update(STATS_STDOUT);
-               tmp_unlink(tmp_stdout);
-               tmp_unlink(tmp_stderr);
-               failed();
-       }
-       tmp_unlink(tmp_stdout);
-
-       // Merge stderr from the preprocessor (if any) and stderr from the real
-       // compiler into tmp_stderr.
-       if (cpp_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();
-               }
-
-               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();
-               }
-
-               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();
-               }
-
-               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);
-               close(fd_real_stderr);
-               close(fd_result);
-               tmp_unlink(tmp_stderr2);
-               free(tmp_stderr2);
-       }
-
-       if (status != 0) {
-               cc_log("Compiler gave exit status %d", status);
-               stats_update(STATS_STATUS);
-
-               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);
-                       close(fd);
-                       tmp_unlink(tmp_stderr);
-
-                       x_exit(status);
-               }
-
-               tmp_unlink(tmp_stderr);
-               failed();
-       }
-
-       if (conf->depend_mode) {
-               struct digest *result_name =
-                       result_name_from_depfile(output_dep, depend_mode_hash);
-               if (!result_name) {
-                       failed();
-               }
-               update_cached_result_globals(result_name);
-       }
-
-       bool produce_dep_file =
-               generating_dependencies && !str_eq(output_dep, "/dev/null");
-
-       if (produce_dep_file) {
-               use_relative_paths_in_depfile(output_dep);
-       }
-
-       if (stat(output_obj, &st) != 0) {
-               cc_log("Compiler didn't produce an object file");
-               stats_update(STATS_NOOUTPUT);
-               failed();
-       }
-       if (st.st_size == 0) {
-               cc_log("Compiler produced an empty object file");
-               stats_update(STATS_EMPTYOUTPUT);
-               failed();
-       }
-
-       if (x_stat(tmp_stderr, &st) != 0) {
-               stats_update(STATS_ERROR);
-               failed();
-       }
-       struct result_files *result_files = result_files_init();
-       if (st.st_size > 0) {
-               result_files_add(result_files, tmp_stderr, RESULT_STDERR_NAME);
-       }
-       result_files_add(result_files, output_obj, ".o");
-       if (generating_dependencies) {
-               result_files_add(result_files, output_dep, ".d");
-       }
-       if (generating_coverage) {
-               result_files_add(result_files, output_cov, ".gcno");
-       }
-       if (generating_stackusage) {
-               result_files_add(result_files, output_su, ".su");
-       }
-       if (generating_diagnostics) {
-               result_files_add(result_files, output_dia, ".dia");
-       }
-       if (seen_split_dwarf && stat(output_dwo, &st) == 0) {
-               // Only copy .dwo file if it was created by the compiler (GCC and Clang
-               // behave differently e.g. for "-gsplit-dwarf -g1").
-               result_files_add(result_files, output_dwo, ".dwo");
-       }
-       struct stat orig_dest_st;
-       bool orig_dest_existed = stat(cached_result_path, &orig_dest_st) == 0;
-       result_put(cached_result_path, result_files);
-       result_files_free(result_files);
-
-       cc_log("Stored in cache: %s", cached_result_path);
-
-       if (x_stat(cached_result_path, &st) != 0) {
-               stats_update(STATS_ERROR);
-               failed();
-       }
-       stats_update_size(
-               stats_file,
-               file_size(&st) - (orig_dest_existed ? file_size(&orig_dest_st) : 0),
-               orig_dest_existed ? 0 : 1);
-
-       MTR_END("file", "file_put");
-
-       stats_update(STATS_TOCACHE);
-
-       // Make sure we have a CACHEDIR.TAG in the cache part of cache_dir. This can
-       // be done almost anywhere, but we might as well do it near the end as we
-       // save the stat call if we exit early.
-       {
-               char *first_level_dir = x_dirname(stats_file);
-               if (create_cachedirtag(first_level_dir) != 0) {
-                       cc_log("Failed to create %s/CACHEDIR.TAG (%s)\n",
-                              first_level_dir, strerror(errno));
-                       stats_update(STATS_ERROR);
-                       failed();
-               }
-               free(first_level_dir);
-
-               // Remove any CACHEDIR.TAG on the cache_dir level where it was located in
-               // previous ccache versions.
-               if (getpid() % 1000 == 0) {
-                       char *path = format("%s/CACHEDIR.TAG", conf->cache_dir);
-                       x_unlink(path);
-                       free(path);
-               }
-       }
-
-       // Everything OK.
-       send_cached_stderr(tmp_stderr);
-       tmp_unlink(tmp_stderr);
-
-       update_manifest_file();
-
-       free(tmp_stderr);
-       free(tmp_stdout);
+  args_add(args, "-o");
+  args_add(args, output_obj);
+
+  if (conf->hard_link) {
+    // Workaround for Clang bug where it overwrites an existing object file
+    // when it's compiling an assembler file, see
+    // <https://bugs.llvm.org/show_bug.cgi?id=39782>.
+    x_unlink(output_obj);
+  }
+
+  if (generating_diagnostics) {
+    args_add(args, "--serialize-diagnostics");
+    args_add(args, output_dia);
+  }
+
+  // Turn off DEPENDENCIES_OUTPUT when running cc1, because otherwise it will
+  // emit a line like this:
+  //
+  //   tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i
+  x_unsetenv("DEPENDENCIES_OUTPUT");
+  x_unsetenv("SUNPRO_DEPENDENCIES");
+
+  if (conf->run_second_cpp) {
+    args_add(args, input_file);
+  } else {
+    args_add(args, i_tmpfile);
+  }
+
+  if (seen_split_dwarf) {
+    // Remove any pre-existing .dwo file since we want to check if the compiler
+    // produced one, intentionally not using x_unlink or tmp_unlink since we're
+    // not interested in logging successful deletions or failures due to
+    // non-existent .dwo files.
+    if (unlink(output_dwo) == -1 && errno != ENOENT) {
+      cc_log("Failed to unlink %s: %s", output_dwo, strerror(errno));
+      stats_update(STATS_BADOUTPUTFILE);
+    }
+  }
+
+  cc_log("Running real compiler");
+  MTR_BEGIN("execute", "compiler");
+  char* tmp_stdout;
+  int tmp_stdout_fd;
+  char* tmp_stderr;
+  int tmp_stderr_fd;
+  int status;
+  if (!conf->depend_mode) {
+    tmp_stdout = format("%s/tmp.stdout", temp_dir());
+    tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
+    tmp_stderr = format("%s/tmp.stderr", temp_dir());
+    tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+    status = execute(args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
+    args_pop(args, 3);
+  } else {
+    // The cached result path is not known yet, use temporary files.
+    tmp_stdout = format("%s/tmp.stdout", temp_dir());
+    tmp_stdout_fd = create_tmp_fd(&tmp_stdout);
+    tmp_stderr = format("%s/tmp.stderr", temp_dir());
+    tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+
+    // Use the original arguments (including dependency options) in depend
+    // mode.
+    assert(orig_args);
+    struct args* depend_mode_args = args_copy(orig_args);
+    args_strip(depend_mode_args, "--ccache-");
+    add_prefix(depend_mode_args, conf->prefix_command);
+
+    time_of_compilation = time(NULL);
+    status = execute(
+      depend_mode_args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
+    args_free(depend_mode_args);
+  }
+  MTR_END("execute", "compiler");
+
+  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);
+    tmp_unlink(tmp_stdout);
+    tmp_unlink(tmp_stderr);
+    failed();
+  }
+
+  // distcc-pump outputs lines like this:
+  // __________Using # distcc servers in pump mode
+  if (st.st_size != 0 && guessed_compiler != GUESSED_PUMP) {
+    cc_log("Compiler produced stdout");
+    stats_update(STATS_STDOUT);
+    tmp_unlink(tmp_stdout);
+    tmp_unlink(tmp_stderr);
+    failed();
+  }
+  tmp_unlink(tmp_stdout);
+
+  // Merge stderr from the preprocessor (if any) and stderr from the real
+  // compiler into tmp_stderr.
+  if (cpp_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();
+    }
+
+    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();
+    }
+
+    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();
+    }
+
+    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);
+    close(fd_real_stderr);
+    close(fd_result);
+    tmp_unlink(tmp_stderr2);
+    free(tmp_stderr2);
+  }
+
+  if (status != 0) {
+    cc_log("Compiler gave exit status %d", status);
+    stats_update(STATS_STATUS);
+
+    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);
+      close(fd);
+      tmp_unlink(tmp_stderr);
+
+      x_exit(status);
+    }
+
+    tmp_unlink(tmp_stderr);
+    failed();
+  }
+
+  if (conf->depend_mode) {
+    struct digest* result_name =
+      result_name_from_depfile(output_dep, depend_mode_hash);
+    if (!result_name) {
+      failed();
+    }
+    update_cached_result_globals(result_name);
+  }
+
+  bool produce_dep_file =
+    generating_dependencies && !str_eq(output_dep, "/dev/null");
+
+  if (produce_dep_file) {
+    use_relative_paths_in_depfile(output_dep);
+  }
+
+  if (stat(output_obj, &st) != 0) {
+    cc_log("Compiler didn't produce an object file");
+    stats_update(STATS_NOOUTPUT);
+    failed();
+  }
+  if (st.st_size == 0) {
+    cc_log("Compiler produced an empty object file");
+    stats_update(STATS_EMPTYOUTPUT);
+    failed();
+  }
+
+  if (x_stat(tmp_stderr, &st) != 0) {
+    stats_update(STATS_ERROR);
+    failed();
+  }
+  struct result_files* result_files = result_files_init();
+  if (st.st_size > 0) {
+    result_files_add(result_files, tmp_stderr, RESULT_STDERR_NAME);
+  }
+  result_files_add(result_files, output_obj, ".o");
+  if (generating_dependencies) {
+    result_files_add(result_files, output_dep, ".d");
+  }
+  if (generating_coverage) {
+    result_files_add(result_files, output_cov, ".gcno");
+  }
+  if (generating_stackusage) {
+    result_files_add(result_files, output_su, ".su");
+  }
+  if (generating_diagnostics) {
+    result_files_add(result_files, output_dia, ".dia");
+  }
+  if (seen_split_dwarf && stat(output_dwo, &st) == 0) {
+    // Only copy .dwo file if it was created by the compiler (GCC and Clang
+    // behave differently e.g. for "-gsplit-dwarf -g1").
+    result_files_add(result_files, output_dwo, ".dwo");
+  }
+  struct stat orig_dest_st;
+  bool orig_dest_existed = stat(cached_result_path, &orig_dest_st) == 0;
+  result_put(cached_result_path, result_files);
+  result_files_free(result_files);
+
+  cc_log("Stored in cache: %s", cached_result_path);
+
+  if (x_stat(cached_result_path, &st) != 0) {
+    stats_update(STATS_ERROR);
+    failed();
+  }
+  stats_update_size(stats_file,
+                    file_size(&st)
+                      - (orig_dest_existed ? file_size(&orig_dest_st) : 0),
+                    orig_dest_existed ? 0 : 1);
+
+  MTR_END("file", "file_put");
+
+  stats_update(STATS_TOCACHE);
+
+  // Make sure we have a CACHEDIR.TAG in the cache part of cache_dir. This can
+  // be done almost anywhere, but we might as well do it near the end as we
+  // save the stat call if we exit early.
+  {
+    char* first_level_dir = x_dirname(stats_file);
+    if (create_cachedirtag(first_level_dir) != 0) {
+      cc_log("Failed to create %s/CACHEDIR.TAG (%s)\n",
+             first_level_dir,
+             strerror(errno));
+      stats_update(STATS_ERROR);
+      failed();
+    }
+    free(first_level_dir);
+
+    // Remove any CACHEDIR.TAG on the cache_dir level where it was located in
+    // previous ccache versions.
+    if (getpid() % 1000 == 0) {
+      char* path = format("%s/CACHEDIR.TAG", conf->cache_dir);
+      x_unlink(path);
+      free(path);
+    }
+  }
+
+  // Everything OK.
+  send_cached_stderr(tmp_stderr);
+  tmp_unlink(tmp_stderr);
+
+  update_manifest_file();
+
+  free(tmp_stderr);
+  free(tmp_stdout);
 }
 
 // Find the result name by running the compiler in preprocessor mode and
 // hashing the result.
-static struct digest *
-get_result_name_from_cpp(struct args *args, struct hash *hash)
+static struct digest*
+get_result_name_from_cpp(struct args* args, struct hash* hash)
 {
-       time_of_compilation = time(NULL);
-
-       char *path_stderr = 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.
-               path_stdout = input_file;
-               status = 0;
-       } else {
-               // Run cpp on the input file to obtain the .i.
-
-               // Limit the basename to 10 characters in order to cope with filesystem with
-               // small maximum filename length limits.
-               char *input_base = x_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);
-               free(input_base);
-               int path_stdout_fd = create_tmp_fd(&path_stdout);
-               add_pending_tmp_file(path_stdout);
-
-               path_stderr = format("%s/tmp.cpp_stderr", temp_dir());
-               int path_stderr_fd = create_tmp_fd(&path_stderr);
-               add_pending_tmp_file(path_stderr);
-
-               int args_added = 2;
-               args_add(args, "-E");
-               if (conf->keep_comments_cpp) {
-                       args_add(args, "-C");
-                       args_added = 3;
-               }
-               args_add(args, input_file);
-               add_prefix(args, conf->prefix_command_cpp);
-               cc_log("Running preprocessor");
-               MTR_BEGIN("execute", "preprocessor");
-               status = execute(args->argv, path_stdout_fd, path_stderr_fd, &compiler_pid);
-               MTR_END("execute", "preprocessor");
-               args_pop(args, args_added);
-       }
-
-       if (status != 0) {
-               cc_log("Preprocessor gave exit status %d", status);
-               stats_update(STATS_PREPROCESSOR);
-               failed();
-       }
-
-       if (conf->unify) {
-               // When we are doing the unifying tricks we need to include the input file
-               // name in the hash to get the warnings right.
-               hash_delimiter(hash, "unifyfilename");
-               hash_string(hash, input_file);
-
-               hash_delimiter(hash, "unifycpp");
-
-               bool debug_unify = getenv("CCACHE_DEBUG_UNIFY");
-               if (unify_hash(hash, path_stdout, debug_unify) != 0) {
-                       stats_update(STATS_ERROR);
-                       cc_log("Failed to unify %s", path_stdout);
-                       failed();
-               }
-       } else {
-               hash_delimiter(hash, "cpp");
-               if (!process_preprocessed_file(hash, path_stdout,
-                                              guessed_compiler == GUESSED_PUMP)) {
-                       stats_update(STATS_ERROR);
-                       failed();
-               }
-       }
-
-       hash_delimiter(hash, "cppstderr");
-       if (!direct_i_file && !hash_file(hash, path_stderr)) {
-               fatal("Failed to open %s: %s", path_stderr, strerror(errno));
-       }
-
-       if (direct_i_file) {
-               i_tmpfile = input_file;
-       } else {
-               // i_tmpfile needs the proper cpp_extension for the compiler to do its
-               // thing correctly
-               i_tmpfile = format("%s.%s", path_stdout, conf->cpp_extension);
-               x_rename(path_stdout, i_tmpfile);
-               add_pending_tmp_file(i_tmpfile);
-       }
-
-       if (conf->run_second_cpp) {
-               free(path_stderr);
-       } else {
-               // If we are using the CPP trick, we need to remember this stderr data and
-               // output it just before the main stderr from the compiler pass.
-               cpp_stderr = path_stderr;
-               hash_delimiter(hash, "runsecondcpp");
-               hash_string(hash, "false");
-       }
-
-       auto name = static_cast<digest*>(x_malloc(sizeof(digest)));
-       hash_result_as_bytes(hash, name);
-       return name;
+  time_of_compilation = time(NULL);
+
+  char* path_stderr = 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.
+    path_stdout = input_file;
+    status = 0;
+  } else {
+    // Run cpp on the input file to obtain the .i.
+
+    // Limit the basename to 10 characters in order to cope with filesystem with
+    // small maximum filename length limits.
+    char* input_base = x_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);
+    free(input_base);
+    int path_stdout_fd = create_tmp_fd(&path_stdout);
+    add_pending_tmp_file(path_stdout);
+
+    path_stderr = format("%s/tmp.cpp_stderr", temp_dir());
+    int path_stderr_fd = create_tmp_fd(&path_stderr);
+    add_pending_tmp_file(path_stderr);
+
+    int args_added = 2;
+    args_add(args, "-E");
+    if (conf->keep_comments_cpp) {
+      args_add(args, "-C");
+      args_added = 3;
+    }
+    args_add(args, input_file);
+    add_prefix(args, conf->prefix_command_cpp);
+    cc_log("Running preprocessor");
+    MTR_BEGIN("execute", "preprocessor");
+    status = execute(args->argv, path_stdout_fd, path_stderr_fd, &compiler_pid);
+    MTR_END("execute", "preprocessor");
+    args_pop(args, args_added);
+  }
+
+  if (status != 0) {
+    cc_log("Preprocessor gave exit status %d", status);
+    stats_update(STATS_PREPROCESSOR);
+    failed();
+  }
+
+  if (conf->unify) {
+    // When we are doing the unifying tricks we need to include the input file
+    // name in the hash to get the warnings right.
+    hash_delimiter(hash, "unifyfilename");
+    hash_string(hash, input_file);
+
+    hash_delimiter(hash, "unifycpp");
+
+    bool debug_unify = getenv("CCACHE_DEBUG_UNIFY");
+    if (unify_hash(hash, path_stdout, debug_unify) != 0) {
+      stats_update(STATS_ERROR);
+      cc_log("Failed to unify %s", path_stdout);
+      failed();
+    }
+  } else {
+    hash_delimiter(hash, "cpp");
+    if (!process_preprocessed_file(
+          hash, path_stdout, guessed_compiler == GUESSED_PUMP)) {
+      stats_update(STATS_ERROR);
+      failed();
+    }
+  }
+
+  hash_delimiter(hash, "cppstderr");
+  if (!direct_i_file && !hash_file(hash, path_stderr)) {
+    fatal("Failed to open %s: %s", path_stderr, strerror(errno));
+  }
+
+  if (direct_i_file) {
+    i_tmpfile = input_file;
+  } else {
+    // i_tmpfile needs the proper cpp_extension for the compiler to do its
+    // thing correctly
+    i_tmpfile = format("%s.%s", path_stdout, conf->cpp_extension);
+    x_rename(path_stdout, i_tmpfile);
+    add_pending_tmp_file(i_tmpfile);
+  }
+
+  if (conf->run_second_cpp) {
+    free(path_stderr);
+  } else {
+    // If we are using the CPP trick, we need to remember this stderr data and
+    // output it just before the main stderr from the compiler pass.
+    cpp_stderr = path_stderr;
+    hash_delimiter(hash, "runsecondcpp");
+    hash_string(hash, "false");
+  }
+
+  auto name = static_cast<digest*>(x_malloc(sizeof(digest)));
+  hash_result_as_bytes(hash, name);
+  return name;
 }
 
 // Hash mtime or content of a file, or the output of a command, according to
 // the CCACHE_COMPILERCHECK setting.
 static void
-hash_compiler(struct hash *hash, struct stat *st, const char *path,
+hash_compiler(struct hash* hash,
+              struct stat* st,
+              const char* path,
               bool allow_command)
 {
-       if (str_eq(conf->compiler_check, "none")) {
-               // Do nothing.
-       } else if (str_eq(conf->compiler_check, "mtime")) {
-               hash_delimiter(hash, "cc_mtime");
-               hash_int(hash, st->st_size);
-               hash_int(hash, st->st_mtime);
-       } else if (str_startswith(conf->compiler_check, "string:")) {
-               hash_delimiter(hash, "cc_hash");
-               hash_string(hash, conf->compiler_check + strlen("string:"));
-       } else if (str_eq(conf->compiler_check, "content") || !allow_command) {
-               hash_delimiter(hash, "cc_content");
-               hash_file(hash, path);
-       } else { // command string
-               bool ok = hash_multicommand_output(
-                       hash, conf->compiler_check, orig_args->argv[0]);
-               if (!ok) {
-                       fatal("Failure running compiler check command: %s", conf->compiler_check);
-               }
-       }
+  if (str_eq(conf->compiler_check, "none")) {
+    // Do nothing.
+  } else if (str_eq(conf->compiler_check, "mtime")) {
+    hash_delimiter(hash, "cc_mtime");
+    hash_int(hash, st->st_size);
+    hash_int(hash, st->st_mtime);
+  } else if (str_startswith(conf->compiler_check, "string:")) {
+    hash_delimiter(hash, "cc_hash");
+    hash_string(hash, conf->compiler_check + strlen("string:"));
+  } else if (str_eq(conf->compiler_check, "content") || !allow_command) {
+    hash_delimiter(hash, "cc_content");
+    hash_file(hash, path);
+  } else { // command string
+    bool ok =
+      hash_multicommand_output(hash, conf->compiler_check, orig_args->argv[0]);
+    if (!ok) {
+      fatal("Failure running compiler check command: %s", conf->compiler_check);
+    }
+  }
 }
 
 // Hash the host compiler(s) invoked by nvcc.
@@ -1604,498 +1630,485 @@ hash_compiler(struct hash *hash, struct stat *st, const char *path,
 // with -ccbin/--compiler-bindir. If they are NULL, the compilers are looked up
 // in PATH instead.
 static void
-hash_nvcc_host_compiler(struct hash *hash, struct stat *ccbin_st,
-                        const char *ccbin)
+hash_nvcc_host_compiler(struct hash* hash,
+                        struct stat* ccbin_st,
+                        const char* ccbin)
 {
-       // From <http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html>:
-       //
-       //   "[...] Specify the directory in which the compiler executable resides.
-       //   The host compiler executable name can be also specified to ensure that
-       //   the correct host compiler is selected."
-       //
-       // and
-       //
-       //   "On all platforms, the default host compiler executable (gcc and g++ on
-       //   Linux, clang and clang++ on Mac OS X, and cl.exe on Windows) found in
-       //   the current execution search path will be used".
-
-       if (!ccbin || S_ISDIR(ccbin_st->st_mode)) {
+  // From <http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html>:
+  //
+  //   "[...] Specify the directory in which the compiler executable resides.
+  //   The host compiler executable name can be also specified to ensure that
+  //   the correct host compiler is selected."
+  //
+  // and
+  //
+  //   "On all platforms, the default host compiler executable (gcc and g++ on
+  //   Linux, clang and clang++ on Mac OS X, and cl.exe on Windows) found in
+  //   the current execution search path will be used".
+
+  if (!ccbin || S_ISDIR(ccbin_st->st_mode)) {
 #if defined(__APPLE__)
-               const char *compilers[] = {"clang", "clang++"};
+    const char* compilers[] = {"clang", "clang++"};
 #elif defined(_WIN32)
-               const char *compilers[] = {"cl.exe"};
+    const char* compilers[] = {"cl.exe"};
 #else
-               const char *compilers[] = {"gcc", "g++"};
+    const char* compilers[] = {"gcc", "g++"};
 #endif
-               for (size_t i = 0; i < ARRAY_SIZE(compilers); i++) {
-                       if (ccbin) {
-                               char *path = format("%s/%s", ccbin, compilers[i]);
-                               struct stat st;
-                               if (stat(path, &st) == 0) {
-                                       hash_compiler(hash, &st, path, false);
-                               }
-                               free(path);
-                       } else {
-                               char *path = find_executable(compilers[i], MYNAME);
-                               if (path) {
-                                       struct stat st;
-                                       x_stat(path, &st);
-                                       hash_compiler(hash, &st, ccbin, false);
-                                       free(path);
-                               }
-                       }
-               }
-       } else {
-               hash_compiler(hash, ccbin_st, ccbin, false);
-       }
+    for (size_t i = 0; i < ARRAY_SIZE(compilers); i++) {
+      if (ccbin) {
+        char* path = format("%s/%s", ccbin, compilers[i]);
+        struct stat st;
+        if (stat(path, &st) == 0) {
+          hash_compiler(hash, &st, path, false);
+        }
+        free(path);
+      } else {
+        char* path = find_executable(compilers[i], MYNAME);
+        if (path) {
+          struct stat st;
+          x_stat(path, &st);
+          hash_compiler(hash, &st, ccbin, false);
+          free(path);
+        }
+      }
+    }
+  } else {
+    hash_compiler(hash, ccbin_st, ccbin, false);
+  }
 }
 
 // Update a hash with information common for the direct and preprocessor modes.
 static void
-hash_common_info(struct args *args, struct hash *hash)
+hash_common_info(struct args* args, struct hash* hash)
 {
-       hash_string(hash, HASH_PREFIX);
+  hash_string(hash, HASH_PREFIX);
 
-       // We have to hash the extension, as a .i file isn't treated the same by the
-       // compiler as a .ii file.
-       hash_delimiter(hash, "ext");
-       hash_string(hash, conf->cpp_extension);
+  // We have to hash the extension, as a .i file isn't treated the same by the
+  // compiler as a .ii file.
+  hash_delimiter(hash, "ext");
+  hash_string(hash, conf->cpp_extension);
 
 #ifdef _WIN32
-       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]);
-       const char *full_path = full_path_win_ext;
+  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]);
+  const char* full_path = full_path_win_ext;
 #else
-       const char *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();
-       }
-
-       // Hash information about the compiler.
-       hash_compiler(hash, &st, args->argv[0], true);
-
-       // Also hash the compiler name as some compilers use hard links and behave
-       // differently depending on the real name.
-       hash_delimiter(hash, "cc_name");
-       char *base = x_basename(args->argv[0]);
-       hash_string(hash, base);
-       free(base);
-
-       if (!(conf->sloppiness & SLOPPY_LOCALE)) {
-               // Hash environment variables that may affect localization of compiler
-               // warning messages.
-               const char *envvars[] = {
-                       "LANG",
-                       "LC_ALL",
-                       "LC_CTYPE",
-                       "LC_MESSAGES",
-                       NULL
-               };
-               for (const char **p = envvars; *p; ++p) {
-                       char *v = getenv(*p);
-                       if (v) {
-                               hash_delimiter(hash, *p);
-                               hash_string(hash, v);
-                       }
-               }
-       }
-
-       // Possibly hash the current working directory.
-       if (generating_debuginfo && conf->hash_dir) {
-               char *cwd = gnu_getcwd();
-               for (size_t i = 0; i < debug_prefix_maps_len; i++) {
-                       char *map = debug_prefix_maps[i];
-                       char *sep = strchr(map, '=');
-                       if (sep) {
-                               char *old_path = x_strndup(map, sep - map);
-                               char* new_path = static_cast<char*>(x_strdup(sep + 1));
-                               cc_log(
-                                       "Relocating debuginfo CWD %s from %s to %s",
-                                       cwd,
-                                       old_path,
-                                       new_path);
-                               if (str_startswith(cwd, old_path)) {
-                                       char *dir = format("%s%s", new_path, cwd + strlen(old_path));
-                                       free(cwd);
-                                       cwd = dir;
-                               }
-                               free(old_path);
-                               free(new_path);
-                       }
-               }
-               if (cwd) {
-                       cc_log("Hashing CWD %s", cwd);
-                       hash_delimiter(hash, "cwd");
-                       hash_string(hash, cwd);
-                       free(cwd);
-               }
-       }
-
-       if (seen_split_dwarf) {
-               // When using -gsplit-dwarf, object files include a link to the
-               // corresponding .dwo file based on the target object filename, so we need
-               // to include the target filename in the hash to avoid handing out an
-               // object file with an incorrect .dwo link.
-               hash_delimiter(hash, "filename");
-               hash_string(hash, x_basename(output_obj));
-       }
-
-       // Possibly hash the coverage data file path.
-       if (generating_coverage && profile_arcs) {
-               char *dir = x_dirname(output_obj);
-               if (profile_dir) {
-                       dir = x_strdup(profile_dir);
-               } else {
-                       char *real_dir = x_realpath(dir);
-                       free(dir);
-                       dir = real_dir;
-               }
-               if (dir) {
-                       char *base_name = x_basename(output_obj);
-                       char *p = remove_extension(base_name);
-                       free(base_name);
-                       char *gcda_path = format("%s/%s.gcda", dir, p);
-                       cc_log("Hashing coverage path %s", gcda_path);
-                       free(p);
-                       hash_delimiter(hash, "gcda");
-                       hash_string(hash, gcda_path);
-                       free(dir);
-               }
-       }
-
-       // Possibly hash the sanitize blacklist file path.
-       for (size_t i = 0; i < sanitize_blacklists_len; i++) {
-               char *sanitize_blacklist = sanitize_blacklists[i];
-               cc_log("Hashing sanitize blacklist %s", sanitize_blacklist);
-               hash_delimiter(hash, "sanitizeblacklist");
-               if (!hash_file(hash, sanitize_blacklist)) {
-                       stats_update(STATS_BADEXTRAFILE);
-                       failed();
-               }
-       }
-
-       if (!str_eq(conf->extra_files_to_hash, "")) {
-               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");
-                       if (!hash_file(hash, path)) {
-                               stats_update(STATS_BADEXTRAFILE);
-                               failed();
-                       }
-                       q = NULL;
-               }
-               free(p);
-       }
-
-       // Possibly hash GCC_COLORS (for color diagnostics).
-       if (guessed_compiler == GUESSED_GCC) {
-               const char *gcc_colors = getenv("GCC_COLORS");
-               if (gcc_colors) {
-                       hash_delimiter(hash, "gcccolors");
-                       hash_string(hash, gcc_colors);
-               }
-       }
+  struct stat st;
+  if (x_stat(full_path, &st) != 0) {
+    stats_update(STATS_COMPILER);
+    failed();
+  }
+
+  // Hash information about the compiler.
+  hash_compiler(hash, &st, args->argv[0], true);
+
+  // Also hash the compiler name as some compilers use hard links and behave
+  // differently depending on the real name.
+  hash_delimiter(hash, "cc_name");
+  char* base = x_basename(args->argv[0]);
+  hash_string(hash, base);
+  free(base);
+
+  if (!(conf->sloppiness & SLOPPY_LOCALE)) {
+    // Hash environment variables that may affect localization of compiler
+    // warning messages.
+    const char* envvars[] = {"LANG", "LC_ALL", "LC_CTYPE", "LC_MESSAGES", NULL};
+    for (const char** p = envvars; *p; ++p) {
+      char* v = getenv(*p);
+      if (v) {
+        hash_delimiter(hash, *p);
+        hash_string(hash, v);
+      }
+    }
+  }
+
+  // Possibly hash the current working directory.
+  if (generating_debuginfo && conf->hash_dir) {
+    char* cwd = gnu_getcwd();
+    for (size_t i = 0; i < debug_prefix_maps_len; i++) {
+      char* map = debug_prefix_maps[i];
+      char* sep = strchr(map, '=');
+      if (sep) {
+        char* old_path = x_strndup(map, sep - map);
+        char* new_path = static_cast<char*>(x_strdup(sep + 1));
+        cc_log(
+          "Relocating debuginfo CWD %s from %s to %s", cwd, old_path, new_path);
+        if (str_startswith(cwd, old_path)) {
+          char* dir = format("%s%s", new_path, cwd + strlen(old_path));
+          free(cwd);
+          cwd = dir;
+        }
+        free(old_path);
+        free(new_path);
+      }
+    }
+    if (cwd) {
+      cc_log("Hashing CWD %s", cwd);
+      hash_delimiter(hash, "cwd");
+      hash_string(hash, cwd);
+      free(cwd);
+    }
+  }
+
+  if (seen_split_dwarf) {
+    // When using -gsplit-dwarf, object files include a link to the
+    // corresponding .dwo file based on the target object filename, so we need
+    // to include the target filename in the hash to avoid handing out an
+    // object file with an incorrect .dwo link.
+    hash_delimiter(hash, "filename");
+    hash_string(hash, x_basename(output_obj));
+  }
+
+  // Possibly hash the coverage data file path.
+  if (generating_coverage && profile_arcs) {
+    char* dir = x_dirname(output_obj);
+    if (profile_dir) {
+      dir = x_strdup(profile_dir);
+    } else {
+      char* real_dir = x_realpath(dir);
+      free(dir);
+      dir = real_dir;
+    }
+    if (dir) {
+      char* base_name = x_basename(output_obj);
+      char* p = remove_extension(base_name);
+      free(base_name);
+      char* gcda_path = format("%s/%s.gcda", dir, p);
+      cc_log("Hashing coverage path %s", gcda_path);
+      free(p);
+      hash_delimiter(hash, "gcda");
+      hash_string(hash, gcda_path);
+      free(dir);
+    }
+  }
+
+  // Possibly hash the sanitize blacklist file path.
+  for (size_t i = 0; i < sanitize_blacklists_len; i++) {
+    char* sanitize_blacklist = sanitize_blacklists[i];
+    cc_log("Hashing sanitize blacklist %s", sanitize_blacklist);
+    hash_delimiter(hash, "sanitizeblacklist");
+    if (!hash_file(hash, sanitize_blacklist)) {
+      stats_update(STATS_BADEXTRAFILE);
+      failed();
+    }
+  }
+
+  if (!str_eq(conf->extra_files_to_hash, "")) {
+    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");
+      if (!hash_file(hash, path)) {
+        stats_update(STATS_BADEXTRAFILE);
+        failed();
+      }
+      q = NULL;
+    }
+    free(p);
+  }
+
+  // Possibly hash GCC_COLORS (for color diagnostics).
+  if (guessed_compiler == GUESSED_GCC) {
+    const char* gcc_colors = getenv("GCC_COLORS");
+    if (gcc_colors) {
+      hash_delimiter(hash, "gcccolors");
+      hash_string(hash, gcc_colors);
+    }
+  }
 }
 
 // Update a hash sum with information specific to the direct and preprocessor
 // modes and calculate the result name. Returns the result name on success,
 // otherwise NULL. Caller frees.
-static struct digest *
-calculate_result_name(struct args *args, struct hash *hash, int direct_mode)
+static struct digest*
+calculate_result_name(struct args* args, struct hash* hash, int direct_mode)
 {
-       bool found_ccbin = false;
-
-       hash_delimiter(hash, "result version");
-       hash_int(hash, RESULT_VERSION);
-
-       if (direct_mode) {
-               hash_delimiter(hash, "manifest version");
-               hash_int(hash, MANIFEST_VERSION);
-       }
-
-       // clang will emit warnings for unused linker flags, so we shouldn't skip
-       // those arguments.
-       int is_clang =
-               guessed_compiler == GUESSED_CLANG || guessed_compiler == GUESSED_UNKNOWN;
-
-       // First the arguments.
-       for (int i = 1; i < args->argc; i++) {
-               // -L doesn't affect compilation (except for clang).
-               if (i < args->argc-1 && str_eq(args->argv[i], "-L") && !is_clang) {
-                       i++;
-                       continue;
-               }
-               if (str_startswith(args->argv[i], "-L") && !is_clang) {
-                       continue;
-               }
-
-               // -Wl,... doesn't affect compilation (except for clang).
-               if (str_startswith(args->argv[i], "-Wl,") && !is_clang) {
-                       continue;
-               }
-
-               // The -fdebug-prefix-map option may be used in combination with
-               // CCACHE_BASEDIR to reuse results across different directories. Skip using
-               // the value of the option from hashing but still hash the existence of the
-               // option.
-               if (str_startswith(args->argv[i], "-fdebug-prefix-map=")) {
-                       hash_delimiter(hash, "arg");
-                       hash_string(hash, "-fdebug-prefix-map=");
-                       continue;
-               }
-               if (str_startswith(args->argv[i], "-ffile-prefix-map=")) {
-                       hash_delimiter(hash, "arg");
-                       hash_string(hash, "-ffile-prefix-map=");
-                       continue;
-               }
-               if (str_startswith(args->argv[i], "-fmacro-prefix-map=")) {
-                       hash_delimiter(hash, "arg");
-                       hash_string(hash, "-fmacro-prefix-map=");
-                       continue;
-               }
-
-               // When using the preprocessor, some arguments don't contribute to the
-               // hash. The theory is that these arguments will change the output of -E if
-               // they are going to have any effect at all. For precompiled headers this
-               // might not be the case.
-               if (!direct_mode && !output_is_precompiled_header
-                   && !using_precompiled_header) {
-                       if (compopt_affects_cpp(args->argv[i])) {
-                               if (compopt_takes_arg(args->argv[i])) {
-                                       i++;
-                               }
-                               continue;
-                       }
-                       if (compopt_short(compopt_affects_cpp, args->argv[i])) {
-                               continue;
-                       }
-               }
-
-               // If we're generating dependencies, we make sure to skip the filename of
-               // the dependency file, since it doesn't impact the output.
-               if (generating_dependencies) {
-                       if (str_startswith(args->argv[i], "-Wp,")) {
-                               if (str_startswith(args->argv[i], "-Wp,-MD,")
-                                   && !strchr(args->argv[i] + 8, ',')) {
-                                       hash_string_buffer(hash, args->argv[i], 8);
-                                       continue;
-                               } else if (str_startswith(args->argv[i], "-Wp,-MMD,")
-                                          && !strchr(args->argv[i] + 9, ',')) {
-                                       hash_string_buffer(hash, args->argv[i], 9);
-                                       continue;
-                               }
-                       } else if (str_startswith(args->argv[i], "-MF")) {
-                               // In either case, hash the "-MF" part.
-                               hash_delimiter(hash, "arg");
-                               hash_string_buffer(hash, args->argv[i], 3);
-
-                               if (!str_eq(output_dep, "/dev/null")) {
-                                       bool separate_argument = (strlen(args->argv[i]) == 3);
-                                       if (separate_argument) {
-                                               // Next argument is dependency name, so skip it.
-                                               i++;
-                                       }
-                               }
-                               continue;
-                       }
-               }
-
-               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.
-                       hash_delimiter(hash, "specs");
-                       hash_compiler(hash, &st, p, false);
-                       continue;
-               }
-
-               if (str_startswith(args->argv[i], "-fplugin=")
-                   && x_stat(args->argv[i] + 9, &st) == 0) {
-                       hash_delimiter(hash, "plugin");
-                       hash_compiler(hash, &st, args->argv[i] + 9, false);
-                       continue;
-               }
-
-               if (str_eq(args->argv[i], "-Xclang")
-                   && i + 3 < args->argc
-                   && str_eq(args->argv[i+1], "-load")
-                   && str_eq(args->argv[i+2], "-Xclang")
-                   && x_stat(args->argv[i+3], &st) == 0) {
-                       hash_delimiter(hash, "plugin");
-                       hash_compiler(hash, &st, args->argv[i+3], false);
-                       i += 3;
-                       continue;
-               }
-
-               if ((str_eq(args->argv[i], "-ccbin")
-                    || str_eq(args->argv[i], "--compiler-bindir"))
-                   && i + 1 < args->argc
-                   && x_stat(args->argv[i+1], &st) == 0) {
-                       found_ccbin = true;
-                       hash_delimiter(hash, "ccbin");
-                       hash_nvcc_host_compiler(hash, &st, args->argv[i+1]);
-                       i++;
-                       continue;
-               }
-
-               // All other arguments are included in the hash.
-               hash_delimiter(hash, "arg");
-               hash_string(hash, args->argv[i]);
-               if (i + 1 < args->argc && compopt_takes_arg(args->argv[i])) {
-                       i++;
-                       hash_delimiter(hash, "arg");
-                       hash_string(hash, args->argv[i]);
-               }
-       }
-
-       // Make results with dependency file /dev/null different from those without
-       // it.
-       if (generating_dependencies && str_eq(output_dep, "/dev/null")) {
-               hash_delimiter(hash, "/dev/null dependency file");
-       }
-
-       if (!found_ccbin && str_eq(actual_language, "cu")) {
-               hash_nvcc_host_compiler(hash, NULL, NULL);
-       }
-
-       // For profile generation (-fprofile-arcs, -fprofile-generate):
-       // - hash profile directory
-       //
-       // For profile usage (-fprofile-use):
-       // - hash profile data
-       //
-       // -fbranch-probabilities and -fvpt usage is covered by
-       // -fprofile-generate/-fprofile-use.
-       //
-       // The profile directory can be specified as an argument to
-       // -fprofile-generate=, -fprofile-use= or -fprofile-dir=.
-       if (profile_generate) {
-               if (!profile_dir) {
-                       profile_dir = get_cwd();
-               }
-               cc_log("Adding profile directory %s to our hash", profile_dir);
-               hash_delimiter(hash, "-fprofile-dir");
-               hash_string(hash, profile_dir);
-       }
-
-       if (profile_use) {
-               // Calculate gcda name.
-               if (!profile_dir) {
-                       profile_dir = get_cwd();
-               }
-               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");
-               hash_file(hash, gcda_name);
-               free(base_name);
-               free(gcda_name);
-       }
-
-       // Adding -arch to hash since cpp output is affected.
-       for (size_t i = 0; i < arch_args_size; ++i) {
-               hash_delimiter(hash, "-arch");
-               hash_string(hash, arch_args[i]);
-       }
-
-       struct digest *result_name = NULL;
-       if (direct_mode) {
-               // Hash environment variables that affect the preprocessor output.
-               const char *envvars[] = {
-                       "CPATH",
-                       "C_INCLUDE_PATH",
-                       "CPLUS_INCLUDE_PATH",
-                       "OBJC_INCLUDE_PATH",
-                       "OBJCPLUS_INCLUDE_PATH", // clang
-                       NULL
-               };
-               for (const char **p = envvars; *p; ++p) {
-                       char *v = getenv(*p);
-                       if (v) {
-                               hash_delimiter(hash, *p);
-                               hash_string(hash, v);
-                       }
-               }
-
-               if (!(conf->sloppiness & SLOPPY_FILE_MACRO)) {
-                       // The source code file or an include file may contain __FILE__, so make
-                       // sure that the hash is unique for the file name.
-                       hash_delimiter(hash, "inputfile");
-                       hash_string(hash, input_file);
-               }
-
-               hash_delimiter(hash, "sourcecode");
-               int result = hash_source_code_file(conf, hash, input_file);
-               if (result & HASH_SOURCE_CODE_ERROR) {
-                       failed();
-               }
-               if (result & HASH_SOURCE_CODE_FOUND_TIME) {
-                       cc_log("Disabling direct mode");
-                       conf->direct_mode = false;
-                       return NULL;
-               }
-
-               char manifest_name_string[DIGEST_STRING_BUFFER_SIZE];
-               hash_result_as_string(hash, manifest_name_string);
-               manifest_path = get_path_in_cache(manifest_name_string, ".manifest");
-               manifest_stats_file =
-                       format("%s/%c/stats", conf->cache_dir, manifest_name_string[0]);
-
-               cc_log("Looking for result name in %s", manifest_path);
-               MTR_BEGIN("manifest", "manifest_get");
-               result_name = manifest_get(conf, manifest_path);
-               MTR_END("manifest", "manifest_get");
-               if (result_name) {
-                       cc_log("Got result name from manifest");
-               } else {
-                       cc_log("Did not find result name in manifest");
-               }
-       } else {
-               if (arch_args_size == 0) {
-                       result_name = get_result_name_from_cpp(args, hash);
-                       cc_log("Got result name from preprocessor");
-               } else {
-                       args_add(args, "-arch");
-                       for (size_t i = 0; i < arch_args_size; ++i) {
-                               args_add(args, arch_args[i]);
-                               result_name = get_result_name_from_cpp(args, hash);
-                               cc_log("Got result name from preprocessor with -arch %s",
-                                      arch_args[i]);
-                               if (i != arch_args_size - 1) {
-                                       free(result_name);
-                                       result_name = NULL;
-                               }
-                               args_pop(args, 1);
-                       }
-                       args_pop(args, 1);
-               }
-               if (generating_dependencies) {
-                       // Nothing is actually created with -MF /dev/null
-                       if (!str_eq(output_dep, "/dev/null")) {
-                               cc_log("Preprocessor created %s", output_dep);
-                       }
-               }
-       }
-
-       return result_name;
+  bool found_ccbin = false;
+
+  hash_delimiter(hash, "result version");
+  hash_int(hash, RESULT_VERSION);
+
+  if (direct_mode) {
+    hash_delimiter(hash, "manifest version");
+    hash_int(hash, MANIFEST_VERSION);
+  }
+
+  // clang will emit warnings for unused linker flags, so we shouldn't skip
+  // those arguments.
+  int is_clang =
+    guessed_compiler == GUESSED_CLANG || guessed_compiler == GUESSED_UNKNOWN;
+
+  // First the arguments.
+  for (int i = 1; i < args->argc; i++) {
+    // -L doesn't affect compilation (except for clang).
+    if (i < args->argc - 1 && str_eq(args->argv[i], "-L") && !is_clang) {
+      i++;
+      continue;
+    }
+    if (str_startswith(args->argv[i], "-L") && !is_clang) {
+      continue;
+    }
+
+    // -Wl,... doesn't affect compilation (except for clang).
+    if (str_startswith(args->argv[i], "-Wl,") && !is_clang) {
+      continue;
+    }
+
+    // The -fdebug-prefix-map option may be used in combination with
+    // CCACHE_BASEDIR to reuse results across different directories. Skip using
+    // the value of the option from hashing but still hash the existence of the
+    // option.
+    if (str_startswith(args->argv[i], "-fdebug-prefix-map=")) {
+      hash_delimiter(hash, "arg");
+      hash_string(hash, "-fdebug-prefix-map=");
+      continue;
+    }
+    if (str_startswith(args->argv[i], "-ffile-prefix-map=")) {
+      hash_delimiter(hash, "arg");
+      hash_string(hash, "-ffile-prefix-map=");
+      continue;
+    }
+    if (str_startswith(args->argv[i], "-fmacro-prefix-map=")) {
+      hash_delimiter(hash, "arg");
+      hash_string(hash, "-fmacro-prefix-map=");
+      continue;
+    }
+
+    // When using the preprocessor, some arguments don't contribute to the
+    // hash. The theory is that these arguments will change the output of -E if
+    // they are going to have any effect at all. For precompiled headers this
+    // might not be the case.
+    if (!direct_mode && !output_is_precompiled_header
+        && !using_precompiled_header) {
+      if (compopt_affects_cpp(args->argv[i])) {
+        if (compopt_takes_arg(args->argv[i])) {
+          i++;
+        }
+        continue;
+      }
+      if (compopt_short(compopt_affects_cpp, args->argv[i])) {
+        continue;
+      }
+    }
+
+    // If we're generating dependencies, we make sure to skip the filename of
+    // the dependency file, since it doesn't impact the output.
+    if (generating_dependencies) {
+      if (str_startswith(args->argv[i], "-Wp,")) {
+        if (str_startswith(args->argv[i], "-Wp,-MD,")
+            && !strchr(args->argv[i] + 8, ',')) {
+          hash_string_buffer(hash, args->argv[i], 8);
+          continue;
+        } else if (str_startswith(args->argv[i], "-Wp,-MMD,")
+                   && !strchr(args->argv[i] + 9, ',')) {
+          hash_string_buffer(hash, args->argv[i], 9);
+          continue;
+        }
+      } else if (str_startswith(args->argv[i], "-MF")) {
+        // In either case, hash the "-MF" part.
+        hash_delimiter(hash, "arg");
+        hash_string_buffer(hash, args->argv[i], 3);
+
+        if (!str_eq(output_dep, "/dev/null")) {
+          bool separate_argument = (strlen(args->argv[i]) == 3);
+          if (separate_argument) {
+            // Next argument is dependency name, so skip it.
+            i++;
+          }
+        }
+        continue;
+      }
+    }
+
+    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.
+      hash_delimiter(hash, "specs");
+      hash_compiler(hash, &st, p, false);
+      continue;
+    }
+
+    if (str_startswith(args->argv[i], "-fplugin=")
+        && x_stat(args->argv[i] + 9, &st) == 0) {
+      hash_delimiter(hash, "plugin");
+      hash_compiler(hash, &st, args->argv[i] + 9, false);
+      continue;
+    }
+
+    if (str_eq(args->argv[i], "-Xclang") && i + 3 < args->argc
+        && str_eq(args->argv[i + 1], "-load")
+        && str_eq(args->argv[i + 2], "-Xclang")
+        && x_stat(args->argv[i + 3], &st) == 0) {
+      hash_delimiter(hash, "plugin");
+      hash_compiler(hash, &st, args->argv[i + 3], false);
+      i += 3;
+      continue;
+    }
+
+    if ((str_eq(args->argv[i], "-ccbin")
+         || str_eq(args->argv[i], "--compiler-bindir"))
+        && i + 1 < args->argc && x_stat(args->argv[i + 1], &st) == 0) {
+      found_ccbin = true;
+      hash_delimiter(hash, "ccbin");
+      hash_nvcc_host_compiler(hash, &st, args->argv[i + 1]);
+      i++;
+      continue;
+    }
+
+    // All other arguments are included in the hash.
+    hash_delimiter(hash, "arg");
+    hash_string(hash, args->argv[i]);
+    if (i + 1 < args->argc && compopt_takes_arg(args->argv[i])) {
+      i++;
+      hash_delimiter(hash, "arg");
+      hash_string(hash, args->argv[i]);
+    }
+  }
+
+  // Make results with dependency file /dev/null different from those without
+  // it.
+  if (generating_dependencies && str_eq(output_dep, "/dev/null")) {
+    hash_delimiter(hash, "/dev/null dependency file");
+  }
+
+  if (!found_ccbin && str_eq(actual_language, "cu")) {
+    hash_nvcc_host_compiler(hash, NULL, NULL);
+  }
+
+  // For profile generation (-fprofile-arcs, -fprofile-generate):
+  // - hash profile directory
+  //
+  // For profile usage (-fprofile-use):
+  // - hash profile data
+  //
+  // -fbranch-probabilities and -fvpt usage is covered by
+  // -fprofile-generate/-fprofile-use.
+  //
+  // The profile directory can be specified as an argument to
+  // -fprofile-generate=, -fprofile-use= or -fprofile-dir=.
+  if (profile_generate) {
+    if (!profile_dir) {
+      profile_dir = get_cwd();
+    }
+    cc_log("Adding profile directory %s to our hash", profile_dir);
+    hash_delimiter(hash, "-fprofile-dir");
+    hash_string(hash, profile_dir);
+  }
+
+  if (profile_use) {
+    // Calculate gcda name.
+    if (!profile_dir) {
+      profile_dir = get_cwd();
+    }
+    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");
+    hash_file(hash, gcda_name);
+    free(base_name);
+    free(gcda_name);
+  }
+
+  // Adding -arch to hash since cpp output is affected.
+  for (size_t i = 0; i < arch_args_size; ++i) {
+    hash_delimiter(hash, "-arch");
+    hash_string(hash, arch_args[i]);
+  }
+
+  struct digest* result_name = NULL;
+  if (direct_mode) {
+    // Hash environment variables that affect the preprocessor output.
+    const char* envvars[] = {"CPATH",
+                             "C_INCLUDE_PATH",
+                             "CPLUS_INCLUDE_PATH",
+                             "OBJC_INCLUDE_PATH",
+                             "OBJCPLUS_INCLUDE_PATH", // clang
+                             NULL};
+    for (const char** p = envvars; *p; ++p) {
+      char* v = getenv(*p);
+      if (v) {
+        hash_delimiter(hash, *p);
+        hash_string(hash, v);
+      }
+    }
+
+    if (!(conf->sloppiness & SLOPPY_FILE_MACRO)) {
+      // The source code file or an include file may contain __FILE__, so make
+      // sure that the hash is unique for the file name.
+      hash_delimiter(hash, "inputfile");
+      hash_string(hash, input_file);
+    }
+
+    hash_delimiter(hash, "sourcecode");
+    int result = hash_source_code_file(conf, hash, input_file);
+    if (result & HASH_SOURCE_CODE_ERROR) {
+      failed();
+    }
+    if (result & HASH_SOURCE_CODE_FOUND_TIME) {
+      cc_log("Disabling direct mode");
+      conf->direct_mode = false;
+      return NULL;
+    }
+
+    char manifest_name_string[DIGEST_STRING_BUFFER_SIZE];
+    hash_result_as_string(hash, manifest_name_string);
+    manifest_path = get_path_in_cache(manifest_name_string, ".manifest");
+    manifest_stats_file =
+      format("%s/%c/stats", conf->cache_dir, manifest_name_string[0]);
+
+    cc_log("Looking for result name in %s", manifest_path);
+    MTR_BEGIN("manifest", "manifest_get");
+    result_name = manifest_get(conf, manifest_path);
+    MTR_END("manifest", "manifest_get");
+    if (result_name) {
+      cc_log("Got result name from manifest");
+    } else {
+      cc_log("Did not find result name in manifest");
+    }
+  } else {
+    if (arch_args_size == 0) {
+      result_name = get_result_name_from_cpp(args, hash);
+      cc_log("Got result name from preprocessor");
+    } else {
+      args_add(args, "-arch");
+      for (size_t i = 0; i < arch_args_size; ++i) {
+        args_add(args, arch_args[i]);
+        result_name = get_result_name_from_cpp(args, hash);
+        cc_log("Got result name from preprocessor with -arch %s", arch_args[i]);
+        if (i != arch_args_size - 1) {
+          free(result_name);
+          result_name = NULL;
+        }
+        args_pop(args, 1);
+      }
+      args_pop(args, 1);
+    }
+    if (generating_dependencies) {
+      // Nothing is actually created with -MF /dev/null
+      if (!str_eq(output_dep, "/dev/null")) {
+        cc_log("Preprocessor created %s", output_dep);
+      }
+    }
+  }
+
+  return result_name;
 }
 
 // Try to return the compile result from cache. If we can return from cache
@@ -2103,1392 +2116,1383 @@ calculate_result_name(struct args *args, struct hash *hash, int direct_mode)
 static void
 from_cache(enum fromcache_call_mode mode, bool put_result_in_manifest)
 {
-       // The user might be disabling cache hits.
-       if (conf->recache) {
-               return;
-       }
-
-       // If we're using Clang, we can't trust a precompiled header object based on
-       // running the preprocessor since clang will produce a fatal error when the
-       // precompiled header is used and one of the included files has an updated
-       // timestamp:
-       //
-       //     file 'foo.h' has been modified since the precompiled header 'foo.pch'
-       //     was built
-       if ((guessed_compiler == GUESSED_CLANG || guessed_compiler == GUESSED_UNKNOWN)
-           && output_is_precompiled_header
-           && mode == FROMCACHE_CPP_MODE) {
-               cc_log("Not considering cached precompiled header in preprocessor mode");
-               return;
-       }
-
-       MTR_BEGIN("cache", "from_cache");
-
-       // (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by gcc.)
-       bool produce_dep_file =
-               generating_dependencies && mode == FROMCACHE_DIRECT_MODE
-               && !str_eq(output_dep, "/dev/null");
-
-       MTR_BEGIN("file", "file_get");
-
-       // Get result from cache.
-       char *tmp_stderr = format("%s/tmp.stderr", temp_dir());
-       int tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
-       close(tmp_stderr_fd);
-
-       struct result_files *result_files = result_files_init();
-       if (!str_eq(output_obj, "/dev/null")) {
-               result_files_add(result_files, output_obj, ".o");
-               if (seen_split_dwarf) {
-                       result_files_add(result_files, output_dwo, ".dwo");
-               }
-       }
-       result_files_add(result_files, tmp_stderr, RESULT_STDERR_NAME);
-       if (produce_dep_file) {
-               result_files_add(result_files, output_dep, ".d");
-       }
-       if (generating_coverage) {
-               result_files_add(result_files, output_cov, ".gcno");
-       }
-       if (generating_stackusage) {
-               result_files_add(result_files, output_su, ".su");
-       }
-       if (generating_diagnostics) {
-               result_files_add(result_files, output_dia, ".dia");
-       }
-       bool ok = result_get(cached_result_path, result_files);
-       result_files_free(result_files);
-       if (!ok) {
-               cc_log("Failed to get result from cache");
-               tmp_unlink(tmp_stderr);
-               free(tmp_stderr);
-               return;
-       }
-
-       MTR_END("file", "file_get");
-
-       send_cached_stderr(tmp_stderr);
-
-       if (put_result_in_manifest) {
-               update_manifest_file();
-       }
-
-       tmp_unlink(tmp_stderr);
-       free(tmp_stderr);
-
-       // Log the cache hit.
-       switch (mode) {
-       case FROMCACHE_DIRECT_MODE:
-               cc_log("Succeeded getting cached result");
-               stats_update(STATS_CACHEHIT_DIR);
-               break;
-
-       case FROMCACHE_CPP_MODE:
-               cc_log("Succeeded getting cached result");
-               stats_update(STATS_CACHEHIT_CPP);
-               break;
-       }
-
-       MTR_END("cache", "from_cache");
-
-       // And exit with the right status code.
-       x_exit(0);
+  // The user might be disabling cache hits.
+  if (conf->recache) {
+    return;
+  }
+
+  // If we're using Clang, we can't trust a precompiled header object based on
+  // running the preprocessor since clang will produce a fatal error when the
+  // precompiled header is used and one of the included files has an updated
+  // timestamp:
+  //
+  //     file 'foo.h' has been modified since the precompiled header 'foo.pch'
+  //     was built
+  if ((guessed_compiler == GUESSED_CLANG || guessed_compiler == GUESSED_UNKNOWN)
+      && output_is_precompiled_header && mode == FROMCACHE_CPP_MODE) {
+    cc_log("Not considering cached precompiled header in preprocessor mode");
+    return;
+  }
+
+  MTR_BEGIN("cache", "from_cache");
+
+  // (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by gcc.)
+  bool produce_dep_file = generating_dependencies
+                          && mode == FROMCACHE_DIRECT_MODE
+                          && !str_eq(output_dep, "/dev/null");
+
+  MTR_BEGIN("file", "file_get");
+
+  // Get result from cache.
+  char* tmp_stderr = format("%s/tmp.stderr", temp_dir());
+  int tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
+  close(tmp_stderr_fd);
+
+  struct result_files* result_files = result_files_init();
+  if (!str_eq(output_obj, "/dev/null")) {
+    result_files_add(result_files, output_obj, ".o");
+    if (seen_split_dwarf) {
+      result_files_add(result_files, output_dwo, ".dwo");
+    }
+  }
+  result_files_add(result_files, tmp_stderr, RESULT_STDERR_NAME);
+  if (produce_dep_file) {
+    result_files_add(result_files, output_dep, ".d");
+  }
+  if (generating_coverage) {
+    result_files_add(result_files, output_cov, ".gcno");
+  }
+  if (generating_stackusage) {
+    result_files_add(result_files, output_su, ".su");
+  }
+  if (generating_diagnostics) {
+    result_files_add(result_files, output_dia, ".dia");
+  }
+  bool ok = result_get(cached_result_path, result_files);
+  result_files_free(result_files);
+  if (!ok) {
+    cc_log("Failed to get result from cache");
+    tmp_unlink(tmp_stderr);
+    free(tmp_stderr);
+    return;
+  }
+
+  MTR_END("file", "file_get");
+
+  send_cached_stderr(tmp_stderr);
+
+  if (put_result_in_manifest) {
+    update_manifest_file();
+  }
+
+  tmp_unlink(tmp_stderr);
+  free(tmp_stderr);
+
+  // Log the cache hit.
+  switch (mode) {
+  case FROMCACHE_DIRECT_MODE:
+    cc_log("Succeeded getting cached result");
+    stats_update(STATS_CACHEHIT_DIR);
+    break;
+
+  case FROMCACHE_CPP_MODE:
+    cc_log("Succeeded getting cached result");
+    stats_update(STATS_CACHEHIT_CPP);
+    break;
+  }
+
+  MTR_END("cache", "from_cache");
+
+  // And exit with the right status code.
+  x_exit(0);
 }
 
 // Find the real compiler. We just search the PATH to find an executable of the
 // same name that isn't a link to ourselves.
 static void
-find_compiler(char **argv)
+find_compiler(char** argv)
 {
-       // We might be being invoked like "ccache gcc -c foo.c".
-       char *base = x_basename(argv[0]);
-       if (same_executable_name(base, MYNAME)) {
-               args_remove_first(orig_args);
-               free(base);
-               if (is_full_path(orig_args->argv[0])) {
-                       // A full path was given.
-                       return;
-               }
-               base = x_basename(orig_args->argv[0]);
-       }
-
-       // Support user override of the compiler.
-       if (!str_eq(conf->compiler, "")) {
-               base = conf->compiler;
-       }
-
-       char *compiler = find_executable(base, MYNAME);
-       if (!compiler) {
-               stats_update(STATS_COMPILER);
-               fatal("Could not find compiler \"%s\" in PATH", base);
-       }
-       if (str_eq(compiler, argv[0])) {
-               fatal("Recursive invocation (the name of the ccache binary must be \"%s\")",
-                     MYNAME);
-       }
-       orig_args->argv[0] = compiler;
+  // We might be being invoked like "ccache gcc -c foo.c".
+  char* base = x_basename(argv[0]);
+  if (same_executable_name(base, MYNAME)) {
+    args_remove_first(orig_args);
+    free(base);
+    if (is_full_path(orig_args->argv[0])) {
+      // A full path was given.
+      return;
+    }
+    base = x_basename(orig_args->argv[0]);
+  }
+
+  // Support user override of the compiler.
+  if (!str_eq(conf->compiler, "")) {
+    base = conf->compiler;
+  }
+
+  char* compiler = find_executable(base, MYNAME);
+  if (!compiler) {
+    stats_update(STATS_COMPILER);
+    fatal("Could not find compiler \"%s\" in PATH", base);
+  }
+  if (str_eq(compiler, argv[0])) {
+    fatal("Recursive invocation (the name of the ccache binary must be \"%s\")",
+          MYNAME);
+  }
+  orig_args->argv[0] = compiler;
 }
 
 bool
-is_precompiled_header(const char *path)
+is_precompiled_header(const charpath)
 {
-       const char *ext = get_extension(path);
-       char *dir = x_dirname(path);
-       const char *dir_ext = get_extension(dir);
-       bool result =
-               str_eq(ext, ".gch")
-               || str_eq(ext, ".pch")
-               || str_eq(ext, ".pth")
-               || str_eq(dir_ext, ".gch"); // See "Precompiled Headers" in GCC docs.
-       free(dir);
-       return result;
+  const char* ext = get_extension(path);
+  char* dir = x_dirname(path);
+  const char* dir_ext = get_extension(dir);
+  bool result =
+    str_eq(ext, ".gch") || str_eq(ext, ".pch") || str_eq(ext, ".pth")
+    || str_eq(dir_ext, ".gch"); // See "Precompiled Headers" in GCC docs.
+  free(dir);
+  return result;
 }
 
 static bool
 color_output_possible(void)
 {
-       const char *term_env = getenv("TERM");
-       return isatty(STDERR_FILENO) && term_env && strcasecmp(term_env, "DUMB") != 0;
+  const char* term_env = getenv("TERM");
+  return isatty(STDERR_FILENO) && term_env && strcasecmp(term_env, "DUMB") != 0;
 }
 
 static bool
-detect_pch(const char *option, const char *arg, bool *found_pch)
+detect_pch(const char* option, const char* arg, bool* found_pch)
 {
-       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);
-                       pch_file = x_strdup(arg);
-               }
-       } else {
-               char *gchpath = format("%s.gch", arg);
-               if (stat(gchpath, &st) == 0) {
-                       cc_log("Detected use of precompiled header: %s", gchpath);
-                       pch_file = x_strdup(gchpath);
-               } else {
-                       char *pchpath = format("%s.pch", arg);
-                       if (stat(pchpath, &st) == 0) {
-                               cc_log("Detected use of precompiled header: %s", pchpath);
-                               pch_file = x_strdup(pchpath);
-                       } else {
-                               // clang may use pretokenized headers.
-                               char *pthpath = format("%s.pth", arg);
-                               if (stat(pthpath, &st) == 0) {
-                                       cc_log("Detected use of pretokenized header: %s", pthpath);
-                                       pch_file = x_strdup(pthpath);
-                               }
-                               free(pthpath);
-                       }
-                       free(pchpath);
-               }
-               free(gchpath);
-       }
-
-       if (pch_file) {
-               if (included_pch_file) {
-                       cc_log("Multiple precompiled headers used: %s and %s\n",
-                              included_pch_file, pch_file);
-                       stats_update(STATS_ARGS);
-                       return false;
-               }
-               included_pch_file = pch_file;
-               *found_pch = true;
-       }
-       return true;
+  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);
+      pch_file = x_strdup(arg);
+    }
+  } else {
+    char* gchpath = format("%s.gch", arg);
+    if (stat(gchpath, &st) == 0) {
+      cc_log("Detected use of precompiled header: %s", gchpath);
+      pch_file = x_strdup(gchpath);
+    } else {
+      char* pchpath = format("%s.pch", arg);
+      if (stat(pchpath, &st) == 0) {
+        cc_log("Detected use of precompiled header: %s", pchpath);
+        pch_file = x_strdup(pchpath);
+      } else {
+        // clang may use pretokenized headers.
+        char* pthpath = format("%s.pth", arg);
+        if (stat(pthpath, &st) == 0) {
+          cc_log("Detected use of pretokenized header: %s", pthpath);
+          pch_file = x_strdup(pthpath);
+        }
+        free(pthpath);
+      }
+      free(pchpath);
+    }
+    free(gchpath);
+  }
+
+  if (pch_file) {
+    if (included_pch_file) {
+      cc_log("Multiple precompiled headers used: %s and %s\n",
+             included_pch_file,
+             pch_file);
+      stats_update(STATS_ARGS);
+      return false;
+    }
+    included_pch_file = pch_file;
+    *found_pch = true;
+  }
+  return true;
 }
 
 // Process the compiler options into options suitable for passing to the
 // preprocessor and the real compiler. The preprocessor options don't include
 // -E; this is added later. Returns true on success, otherwise false.
 bool
-cc_process_args(struct args *args, struct args **preprocessor_args,
-                struct args **compiler_args)
+cc_process_args(struct args* args,
+                struct args** preprocessor_args,
+                struct args** compiler_args)
 {
-       bool found_c_opt = false;
-       bool found_dc_opt = false;
-       bool found_S_opt = false;
-       bool found_pch = false;
-       bool found_fpch_preprocess = false;
-       const char *explicit_language = NULL; // As specified with -x.
-       const char *file_language;            // As deduced from file extension.
-       const char *input_charset = NULL;
-
-       // Is the dependency makefile name overridden with -MF?
-       bool dependency_filename_specified = false;
-
-       // Is the dependency makefile target name specified with -MT or -MQ?
-       bool dependency_target_specified = false;
-
-       // Is the dependency target name implicitly specified using
-       // DEPENDENCIES_OUTPUT or SUNPRO_DEPENDENCIES?
-       bool dependency_implicit_target_specified = false;
-
-       // 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 = args_copy(args);
-
-       // common_args contains all original arguments except:
-       // * those that never should be passed to the preprocessor,
-       // * those that only should be passed to the preprocessor (if run_second_cpp
-       //   is false), and
-       // * dependency options (like -MD and friends).
-       struct args *common_args = args_init(0, NULL);
-
-       // cpp_args contains arguments that were not added to common_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 = args_init(0, NULL);
-
-       // dep_args contains dependency options like -MD. They are only passed to the
-       // preprocessor, never to the compiler.
-       struct args *dep_args = args_init(0, NULL);
-
-       // compiler_only_args contains arguments that should only be passed to the
-       // compiler, not the preprocessor.
-       struct args *compiler_only_args = args_init(0, NULL);
-
-       bool found_color_diagnostics = false;
-       bool found_directives_only = false;
-       bool found_rewrite_includes = false;
-
-       int argc = expanded_args->argc;
-       char **argv = expanded_args->argv;
-       args_add(common_args, argv[0]);
-
-       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++;
-                       if (i == argc) {
-                               cc_log("--ccache-skip lacks an argument");
-                               result = false;
-                               goto out;
-                       }
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-
-               // Special case for -E.
-               if (str_eq(argv[i], "-E")) {
-                       stats_update(STATS_PREPROCESSING);
-                       result = false;
-                       goto out;
-               }
-
-               // Handle "@file" argument.
-               if (str_startswith(argv[i], "@") || str_startswith(argv[i], "-@")) {
-                       char *argpath = argv[i] + 1;
-
-                       if (argpath[-1] == '-') {
-                               ++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);
-                               result = false;
-                               goto out;
-                       }
-
-                       args_insert(expanded_args, i, file_args, true);
-                       argc = expanded_args->argc;
-                       argv = expanded_args->argv;
-                       i--;
-                       continue;
-               }
-
-               // Handle cuda "-optf" and "--options-file" argument.
-               if (guessed_compiler == GUESSED_NVCC
-                   && (str_eq(argv[i], "-optf") || str_eq(argv[i], "--options-file"))) {
-                       if (i == argc - 1) {
-                               cc_log("Expected argument after %s", argv[i]);
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
-                       }
-                       ++i;
-
-                       // Argument is a comma-separated list of files.
-                       char *str_start = argv[i];
-                       char *str_end = strchr(str_start, ',');
-                       int index = i + 1;
-
-                       if (!str_end) {
-                               str_end = str_start + strlen(str_start);
-                       }
-
-                       while (str_end) {
-                               *str_end = '\0';
-                               struct args *file_args = args_init_from_gcc_atfile(str_start);
-                               if (!file_args) {
-                                       cc_log("Couldn't read cuda options file %s", str_start);
-                                       stats_update(STATS_ARGS);
-                                       result = false;
-                                       goto out;
-                               }
-
-                               int new_index = file_args->argc + index;
-                               args_insert(expanded_args, index, file_args, false);
-                               index = new_index;
-                               str_start = str_end;
-                               str_end = strchr(str_start, ',');
-                       }
-
-                       argc = expanded_args->argc;
-                       argv = expanded_args->argv;
-                       continue;
-               }
-
-               // These are always too hard.
-               if (compopt_too_hard(argv[i]) || str_startswith(argv[i], "-fdump-")) {
-                       cc_log("Compiler option %s is unsupported", argv[i]);
-                       stats_update(STATS_UNSUPPORTED_OPTION);
-                       result = false;
-                       goto out;
-               }
-
-               // These are too hard in direct mode.
-               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.
-               if (str_startswith(argv[i], "-Xarch_")) {
-                       cc_log("Unsupported compiler option :%s", argv[i]);
-                       stats_update(STATS_UNSUPPORTED_OPTION);
-                       result = false;
-                       goto out;
-               }
-
-               // Handle -arch options.
-               if (str_eq(argv[i], "-arch")) {
-                       if (arch_args_size == MAX_ARCH_ARGS - 1) {
-                               cc_log("Too many -arch compiler options; ccache supports at most %d",
-                                      MAX_ARCH_ARGS);
-                               stats_update(STATS_UNSUPPORTED_OPTION);
-                               result = false;
-                               goto out;
-                       }
-
-                       ++i;
-                       arch_args[arch_args_size] = x_strdup(argv[i]); // It will leak.
-                       ++arch_args_size;
-                       if (arch_args_size == 2) {
-                               conf->run_second_cpp = true;
-                       }
-                       continue;
-               }
-
-               // Handle options that should not be passed to the preprocessor.
-               if (compopt_affects_comp(argv[i])) {
-                       args_add(compiler_only_args, argv[i]);
-                       if (compopt_takes_arg(argv[i])) {
-                               if (i == argc - 1) {
-                                       cc_log("Missing argument to %s", argv[i]);
-                                       stats_update(STATS_ARGS);
-                                       result = false;
-                                       goto out;
-                               }
-                               args_add(compiler_only_args, argv[i + 1]);
-                               ++i;
-                       }
-                       continue;
-               }
-               if (compopt_prefix_affects_comp(argv[i])) {
-                       args_add(compiler_only_args, argv[i]);
-                       continue;
-               }
-
-               if (str_eq(argv[i], "-fpch-preprocess")
-                   || str_eq(argv[i], "-emit-pch")
-                   || str_eq(argv[i], "-emit-pth")) {
-                       found_fpch_preprocess = true;
-               }
-
-               // We must have -c.
-               if (str_eq(argv[i], "-c")) {
-                       found_c_opt = true;
-                       continue;
-               }
-
-               // when using nvcc with separable compilation, -dc implies -c
-               if ((str_eq(argv[i], "-dc") || str_eq(argv[i], "--device-c")) && guessed_compiler == GUESSED_NVCC) {
-                       found_dc_opt = true;
-                       continue;
-               }
-
-               // -S changes the default extension.
-               if (str_eq(argv[i], "-S")) {
-                       args_add(common_args, argv[i]);
-                       found_S_opt = true;
-                       continue;
-               }
-
-               // Special handling for -x: remember the last specified language before the
-               // input file and strip all -x options from the arguments.
-               if (str_eq(argv[i], "-x")) {
-                       if (i == argc - 1) {
-                               cc_log("Missing argument to %s", argv[i]);
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
-                       }
-                       if (!input_file) {
-                               explicit_language = argv[i+1];
-                       }
-                       i++;
-                       continue;
-               }
-               if (str_startswith(argv[i], "-x")) {
-                       if (!input_file) {
-                               explicit_language = &argv[i][2];
-                       }
-                       continue;
-               }
-
-               // We need to work out where the output was meant to go.
-               if (str_eq(argv[i], "-o")) {
-                       if (i == argc - 1) {
-                               cc_log("Missing argument to %s", argv[i]);
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
-                       }
-                       output_obj = make_relative_path(x_strdup(argv[i+1]));
-                       i++;
-                       continue;
-               }
-
-               // Alternate form of -o with no space. Nvcc does not support this.
-               if (str_startswith(argv[i], "-o") && guessed_compiler != GUESSED_NVCC) {
-                       output_obj = make_relative_path(x_strdup(&argv[i][2]));
-                       continue;
-               }
-
-               if (str_startswith(argv[i], "-fdebug-prefix-map=")
-                   || str_startswith(argv[i], "-ffile-prefix-map=")) {
-                       debug_prefix_maps = static_cast<char**>(
-                               x_realloc(
-                                       debug_prefix_maps,
-                                       (debug_prefix_maps_len + 1) * sizeof(char *)));
-                       debug_prefix_maps[debug_prefix_maps_len++] =
-                               x_strdup(&argv[i][argv[i][2] == 'f' ? 18 : 19]);
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-
-               // Debugging is handled specially, so that we know if we can strip line
-               // number info.
-               if (str_startswith(argv[i], "-g")) {
-                       args_add(common_args, argv[i]);
-
-                       if (str_startswith(argv[i], "-gdwarf")) {
-                               // Selection of DWARF format (-gdwarf or -gdwarf-<version>) enables
-                               // debug info on level 2.
-                               generating_debuginfo = true;
-                               continue;
-                       }
-
-                       char last_char = argv[i][strlen(argv[i]) - 1];
-                       if (last_char == '0') {
-                               // "-g0", "-ggdb0" or similar: All debug information disabled.
-                               generating_debuginfo = false;
-                               generating_debuginfo_level_3 = false;
-                       } else {
-                               generating_debuginfo = true;
-                               if (last_char == '3') {
-                                       generating_debuginfo_level_3 = true;
-                               }
-                               if (str_eq(argv[i], "-gsplit-dwarf")) {
-                                       seen_split_dwarf = true;
-                               }
-                       }
-                       continue;
-               }
-
-               // These options require special handling, because they behave differently
-               // with gcc -E, when the output file is not specified.
-               if (str_eq(argv[i], "-MD") || str_eq(argv[i], "-MMD")) {
-                       generating_dependencies = true;
-                       args_add(dep_args, argv[i]);
-                       continue;
-               }
-               if (str_startswith(argv[i], "-MF")) {
-                       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) {
-                                       cc_log("Missing argument to %s", argv[i]);
-                                       stats_update(STATS_ARGS);
-                                       result = false;
-                                       goto out;
-                               }
-                               arg = argv[i + 1];
-                               i++;
-                       } else {
-                               // -MFarg
-                               arg = &argv[i][3];
-                       }
-                       output_dep = make_relative_path(x_strdup(arg));
-                       // Keep the format of the args the same.
-                       if (separate_argument) {
-                               args_add(dep_args, "-MF");
-                               args_add(dep_args, output_dep);
-                       } else {
-                               char *option = format("-MF%s", output_dep);
-                               args_add(dep_args, option);
-                               free(option);
-                       }
-                       continue;
-               }
-               if (str_startswith(argv[i], "-MQ") || str_startswith(argv[i], "-MT")) {
-                       dependency_target_specified = true;
-
-                       char *relpath;
-                       if (strlen(argv[i]) == 3) {
-                               // -MQ arg or -MT arg
-                               if (i == argc - 1) {
-                                       cc_log("Missing argument to %s", argv[i]);
-                                       stats_update(STATS_ARGS);
-                                       result = false;
-                                       goto out;
-                               }
-                               args_add(dep_args, argv[i]);
-                               relpath = make_relative_path(x_strdup(argv[i + 1]));
-                               args_add(dep_args, relpath);
-                               free(relpath);
-                               i++;
-                       } else {
-                               char *arg_opt = x_strndup(argv[i], 3);
-                               relpath = make_relative_path(x_strdup(argv[i] + 3));
-                               char *option = format("%s%s", arg_opt, relpath);
-                               args_add(dep_args, option);
-                               free(arg_opt);
-                               free(relpath);
-                               free(option);
-                       }
-                       continue;
-               }
-               if (str_eq(argv[i], "-fprofile-arcs")) {
-                       profile_arcs = true;
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-               if (str_eq(argv[i], "-ftest-coverage")) {
-                       generating_coverage = true;
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-               if (str_eq(argv[i], "-fstack-usage")) {
-                       generating_stackusage = true;
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-               if (str_eq(argv[i], "--coverage") // = -fprofile-arcs -ftest-coverage
-                   || str_eq(argv[i], "-coverage")) { // Undocumented but still works.
-                       profile_arcs = true;
-                       generating_coverage = true;
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-               if (str_startswith(argv[i], "-fprofile-dir=")) {
-                       profile_dir = x_strdup(argv[i] + 14);
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-               if (str_startswith(argv[i], "-fsanitize-blacklist=")) {
-                       sanitize_blacklists = static_cast<char**>(
-                               x_realloc(
-                                       sanitize_blacklists,
-                                       (sanitize_blacklists_len + 1) * sizeof(char *)));
-                       sanitize_blacklists[sanitize_blacklists_len++] = x_strdup(argv[i] + 21);
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-               if (str_startswith(argv[i], "--sysroot=")) {
-                       char *relpath = make_relative_path(x_strdup(argv[i] + 10));
-                       char *option = format("--sysroot=%s", relpath);
-                       args_add(common_args, option);
-                       free(relpath);
-                       free(option);
-                       continue;
-               }
-               // Alternate form of specifying sysroot without =
-               if (str_eq(argv[i], "--sysroot")) {
-                       if (i == argc-1) {
-                               cc_log("Missing argument to %s", argv[i]);
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
-                       }
-                       args_add(common_args, argv[i]);
-                       char *relpath = make_relative_path(x_strdup(argv[i+1]));
-                       args_add(common_args, relpath);
-                       i++;
-                       free(relpath);
-                       continue;
-               }
-               // Alternate form of specifying target without =
-               if (str_eq(argv[i], "-target")) {
-                       if (i == argc-1) {
-                               cc_log("Missing argument to %s", argv[i]);
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
-                       }
-                       args_add(common_args, argv[i]);
-                       args_add(common_args, argv[i+1]);
-                       i++;
-                       continue;
-               }
-               if (str_startswith(argv[i], "-Wp,")) {
-                       if (str_eq(argv[i], "-Wp,-P")
-                           || strstr(argv[i], ",-P,")
-                           || str_endswith(argv[i], ",-P")) {
-                               // -P removes preprocessor information in such a way that the object
-                               // file from compiling the preprocessed file will not be equal to the
-                               // object file produced when compiling without ccache.
-                               cc_log("Too hard option -Wp,-P detected");
-                               stats_update(STATS_UNSUPPORTED_OPTION);
-                               failed();
-                       } else if (str_startswith(argv[i], "-Wp,-MD,")
-                                  && !strchr(argv[i] + 8, ',')) {
-                               generating_dependencies = true;
-                               dependency_filename_specified = true;
-                               free(output_dep);
-                               output_dep = make_relative_path(x_strdup(argv[i] + 8));
-                               args_add(dep_args, argv[i]);
-                               continue;
-                       } else if (str_startswith(argv[i], "-Wp,-MMD,")
-                                  && !strchr(argv[i] + 9, ',')) {
-                               generating_dependencies = true;
-                               dependency_filename_specified = true;
-                               free(output_dep);
-                               output_dep = make_relative_path(x_strdup(argv[i] + 9));
-                               args_add(dep_args, argv[i]);
-                               continue;
-                       } else if (str_startswith(argv[i], "-Wp,-D")
-                                  && !strchr(argv[i] + 6, ',')) {
-                               // Treat it like -D.
-                               args_add(cpp_args, argv[i] + 4);
-                               continue;
-                       } else if (str_eq(argv[i], "-Wp,-MP")
-                                  || (strlen(argv[i]) > 8
-                                      && str_startswith(argv[i], "-Wp,-M")
-                                      && argv[i][7] == ','
-                                      && (argv[i][6] == 'F'
-                                          || argv[i][6] == 'Q'
-                                          || argv[i][6] == 'T')
-                                      && !strchr(argv[i] + 8, ','))) {
-                               // TODO: Make argument to MF/MQ/MT relative.
-                               args_add(dep_args, argv[i]);
-                               continue;
-                       } else if (conf->direct_mode) {
-                               // -Wp, can be used to pass too hard options to the preprocessor.
-                               // Hence, disable direct mode.
-                               cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
-                               conf->direct_mode = false;
-                       }
-
-                       // Any other -Wp,* arguments are only relevant for the preprocessor.
-                       args_add(cpp_args, argv[i]);
-                       continue;
-               }
-               if (str_eq(argv[i], "-MP")) {
-                       args_add(dep_args, argv[i]);
-                       continue;
-               }
-
-               // Input charset needs to be handled specially.
-               if (str_startswith(argv[i], "-finput-charset=")) {
-                       input_charset = argv[i];
-                       continue;
-               }
-
-               if (str_eq(argv[i], "--serialize-diagnostics")) {
-                       if (i == argc - 1) {
-                               cc_log("Missing argument to %s", argv[i]);
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
-                       }
-                       generating_diagnostics = true;
-                       output_dia = make_relative_path(x_strdup(argv[i+1]));
-                       i++;
-                       continue;
-               }
-
-               if (str_startswith(argv[i], "-fprofile-")) {
-                       char *arg = x_strdup(argv[i]);
-                       const char *arg_profile_dir = strchr(argv[i], '=');
-                       if (arg_profile_dir) {
-                               // Convert to absolute path.
-                               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;
-                               supported_profile_option = true;
-                       } else if (str_startswith(argv[i], "-fprofile-use")
-                                  || str_eq(argv[i], "-fbranch-probabilities")) {
-                               profile_use = true;
-                               supported_profile_option = true;
-                       } else if (str_eq(argv[i], "-fprofile-dir")) {
-                               supported_profile_option = true;
-                       }
-
-                       if (supported_profile_option) {
-                               args_add(common_args, arg);
-                               free(arg);
-
-                               // If the profile directory has already been set, give up... Hard to
-                               // know what the user means, and what the compiler will do.
-                               if (arg_profile_dir && profile_dir) {
-                                       cc_log("Profile directory already set; giving up");
-                                       result = false;
-                                       goto out;
-                               } else if (arg_profile_dir) {
-                                       cc_log("Setting profile directory to %s", arg_profile_dir);
-                                       profile_dir = x_strdup(arg_profile_dir);
-                               }
-                               continue;
-                       }
-                       cc_log("Unknown profile option: %s", argv[i]);
-                       free(arg);
-               }
-
-               if (str_eq(argv[i], "-fcolor-diagnostics")
-                   || str_eq(argv[i], "-fno-color-diagnostics")
-                   || str_eq(argv[i], "-fdiagnostics-color")
-                   || str_eq(argv[i], "-fdiagnostics-color=always")
-                   || str_eq(argv[i], "-fno-diagnostics-color")
-                   || str_eq(argv[i], "-fdiagnostics-color=never")) {
-                       args_add(common_args, argv[i]);
-                       found_color_diagnostics = true;
-                       continue;
-               }
-               if (str_eq(argv[i], "-fdiagnostics-color=auto")) {
-                       if (color_output_possible()) {
-                               // Output is redirected, so color output must be forced.
-                               args_add(common_args, "-fdiagnostics-color=always");
-                               cc_log("Automatically forcing colors");
-                       } else {
-                               args_add(common_args, argv[i]);
-                       }
-                       found_color_diagnostics = true;
-                       continue;
-               }
-
-               // GCC
-               if (str_eq(argv[i], "-fdirectives-only")) {
-                       found_directives_only = true;
-                       continue;
-               }
-               // Clang
-               if (str_eq(argv[i], "-frewrite-includes")) {
-                       found_rewrite_includes = true;
-                       continue;
-               }
-
-               if (conf->sloppiness & SLOPPY_CLANG_INDEX_STORE
-                   && str_eq(argv[i], "-index-store-path")) {
-                       // Xcode 9 or later calls Clang with this option. The given path includes
-                       // a UUID that might lead to cache misses, especially when cache is
-                       // shared among multiple users.
-                       i++;
-                       if (i <= argc - 1) {
-                               cc_log("Skipping argument -index-store-path %s", argv[i]);
-                       }
-                       continue;
-               }
-
-               // Options taking an argument that we may want to rewrite to relative paths
-               // 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])) {
-                       if (i == argc - 1) {
-                               cc_log("Missing argument to %s", argv[i]);
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
-                       }
-
-                       if (!detect_pch(argv[i], argv[i+1], &found_pch)) {
-                               result = false;
-                               goto out;
-                       }
-
-                       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);
-                       } else {
-                               args_add(common_args, argv[i]);
-                               args_add(common_args, relpath);
-                       }
-                       free(relpath);
-
-                       i++;
-                       continue;
-               }
-
-               // Same as above but options with concatenated argument beginning with a
-               // slash.
-               if (argv[i][0] == '-') {
-                       char *slash_pos = strchr(argv[i], '/');
-                       if (slash_pos) {
-                               char *option = x_strndup(argv[i], slash_pos - argv[i]);
-                               if (compopt_takes_concat_arg(option) && compopt_takes_path(option)) {
-                                       char *relpath = make_relative_path(x_strdup(slash_pos));
-                                       char *new_option = format("%s%s", option, relpath);
-                                       if (compopt_affects_cpp(option)) {
-                                               args_add(cpp_args, new_option);
-                                       } else {
-                                               args_add(common_args, new_option);
-                                       }
-                                       free(new_option);
-                                       free(relpath);
-                                       free(option);
-                                       continue;
-                               } else {
-                                       free(option);
-                               }
-                       }
-               }
-
-               // Options that take an argument.
-               if (compopt_takes_arg(argv[i])) {
-                       if (i == argc - 1) {
-                               cc_log("Missing argument to %s", argv[i]);
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
-                       }
-
-                       if (compopt_affects_cpp(argv[i])) {
-                               args_add(cpp_args, argv[i]);
-                               args_add(cpp_args, argv[i+1]);
-                       } else {
-                               args_add(common_args, argv[i]);
-                               args_add(common_args, argv[i+1]);
-                       }
-
-                       i++;
-                       continue;
-               }
-
-               // Other options.
-               if (argv[i][0] == '-') {
-                       if (compopt_affects_cpp(argv[i])
-                           || compopt_prefix_affects_cpp(argv[i])) {
-                               args_add(cpp_args, argv[i]);
-                       } else {
-                               args_add(common_args, argv[i]);
-                       }
-                       continue;
-               }
-
-               // 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.
-               //
-               // Note that "/dev/null" is an exception that is sometimes used as an input
-               // file when code is testing compiler flags.
-               struct stat st;
-               if (!str_eq(argv[i], "/dev/null")
-                   && (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]);
-                       args_add(common_args, argv[i]);
-                       continue;
-               }
-
-               if (input_file) {
-                       if (language_for_file(argv[i])) {
-                               cc_log("Multiple input files: %s and %s", input_file, argv[i]);
-                               stats_update(STATS_MULTIPLE);
-                       } else if (!found_c_opt && !found_dc_opt) {
-                               cc_log("Called for link with %s", argv[i]);
-                               if (strstr(argv[i], "conftest.")) {
-                                       stats_update(STATS_CONFTEST);
-                               } else {
-                                       stats_update(STATS_LINK);
-                               }
-                       } else {
-                               cc_log("Unsupported source extension: %s", argv[i]);
-                               stats_update(STATS_SOURCELANG);
-                       }
-                       result = false;
-                       goto out;
-               }
-
-               // The source code file path gets put into the notes.
-               if (generating_coverage) {
-                       input_file = x_strdup(argv[i]);
-                       continue;
-               }
-
-               if (is_symlink(argv[i])) {
-                       // Don't rewrite source file path if it's a symlink since
-                       // make_relative_path resolves symlinks using realpath(3) and this leads
-                       // to potentially choosing incorrect relative header files. See the
-                       // "symlink to source file" test.
-                       input_file = x_strdup(argv[i]);
-               } else {
-                       // Rewrite to relative to increase hit rate.
-                       input_file = make_relative_path(x_strdup(argv[i]));
-               }
-       } // for
-
-       if (generating_debuginfo && conf->unify) {
-               cc_log("Generating debug info; disabling unify mode");
-               conf->unify = false;
-       }
-
-       if (generating_debuginfo_level_3 && !conf->run_second_cpp) {
-               cc_log("Generating debug info level 3; not compiling preprocessed code");
-               conf->run_second_cpp = true;
-       }
-
-       // See <http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html>.
-       // Contrary to what the documentation seems to imply the compiler still
-       // creates object files with these defined (confirmed with GCC 8.2.1), i.e.
-       // they work as -MMD/-MD, not -MM/-M. These environment variables do nothing
-       // on Clang.
-       {
-               char *dependencies_env = getenv("DEPENDENCIES_OUTPUT");
-               bool using_sunpro_dependencies = false;
-               if (!dependencies_env) {
-                       dependencies_env = getenv("SUNPRO_DEPENDENCIES");
-                       using_sunpro_dependencies = true;
-               }
-               if (dependencies_env) {
-                       generating_dependencies = true;
-                       dependency_filename_specified = true;
-                       char *saveptr = nullptr;
-                       char *abspath_file = strtok_r(dependencies_env, " ", &saveptr);
-
-                       free(output_dep);
-                       output_dep = make_relative_path(x_strdup(abspath_file));
-
-                       // specifying target object is optional.
-                       char *abspath_obj = strtok_r(nullptr, " ", &saveptr);
-                       if (abspath_obj) {
-                               // it's the "file target" form.
-
-                               dependency_target_specified = true;
-                               char *relpath_obj = make_relative_path(x_strdup(abspath_obj));
-                               // ensure compiler gets relative path.
-                               char *relpath_both = format("%s %s", output_dep, relpath_obj);
-                               if (using_sunpro_dependencies) {
-                                       x_setenv("SUNPRO_DEPENDENCIES", relpath_both);
-                               } else {
-                                       x_setenv("DEPENDENCIES_OUTPUT", relpath_both);
-                               }
-                               free(relpath_obj);
-                               free(relpath_both);
-                       } else {
-                               // it's the "file" form.
-
-                               dependency_implicit_target_specified = true;
-                               // ensure compiler gets relative path.
-                               if (using_sunpro_dependencies) {
-                                       x_setenv("SUNPRO_DEPENDENCIES", output_dep);
-                               } else {
-                                       x_setenv("DEPENDENCIES_OUTPUT", output_dep);
-                               }
-                       }
-               }
-       }
-
-       if (!input_file) {
-               cc_log("No input file found");
-               stats_update(STATS_NOINPUT);
-               result = false;
-               goto out;
-       }
-
-       if (found_pch || found_fpch_preprocess) {
-               using_precompiled_header = true;
-               if (!(conf->sloppiness & SLOPPY_TIME_MACROS)) {
-                       cc_log("You have to specify \"time_macros\" sloppiness when using"
-                              " precompiled headers to get direct hits");
-                       cc_log("Disabling direct mode");
-                       stats_update(STATS_CANTUSEPCH);
-                       result = false;
-                       goto out;
-               }
-       }
-
-       if (explicit_language && str_eq(explicit_language, "none")) {
-               explicit_language = NULL;
-       }
-       file_language = language_for_file(input_file);
-       if (explicit_language) {
-               if (!language_is_supported(explicit_language)) {
-                       cc_log("Unsupported language: %s", explicit_language);
-                       stats_update(STATS_SOURCELANG);
-                       result = false;
-                       goto out;
-               }
-               actual_language = x_strdup(explicit_language);
-       } else {
-               actual_language = file_language;
-       }
-
-       output_is_precompiled_header =
-               actual_language && strstr(actual_language, "-header");
-
-       if (output_is_precompiled_header
-           && !(conf->sloppiness & SLOPPY_PCH_DEFINES)) {
-               cc_log("You have to specify \"pch_defines,time_macros\" sloppiness when"
-                      " creating precompiled headers");
-               stats_update(STATS_CANTUSEPCH);
-               result = false;
-               goto out;
-       }
-
-       if (!found_c_opt && !found_dc_opt && !found_S_opt) {
-               if (output_is_precompiled_header) {
-                       args_add(common_args, "-c");
-               } else {
-                       cc_log("No -c option found");
-                       // I find that having a separate statistic for autoconf tests is useful,
-                       // as they are the dominant form of "called for link" in many cases.
-                       if (strstr(input_file, "conftest.")) {
-                               stats_update(STATS_CONFTEST);
-                       } else {
-                               stats_update(STATS_LINK);
-                       }
-                       result = false;
-                       goto out;
-               }
-       }
-
-       if (!actual_language) {
-               cc_log("Unsupported source extension: %s", input_file);
-               stats_update(STATS_SOURCELANG);
-               result = false;
-               goto out;
-       }
-
-       if (!conf->run_second_cpp && str_eq(actual_language, "cu")) {
-               cc_log("Using CUDA compiler; not compiling preprocessed code");
-               conf->run_second_cpp = true;
-       }
-
-       direct_i_file = language_is_preprocessed(actual_language);
-
-       if (output_is_precompiled_header && !conf->run_second_cpp) {
-               // It doesn't work to create the .gch from preprocessed source.
-               cc_log("Creating precompiled header; not compiling preprocessed code");
-               conf->run_second_cpp = true;
-       }
-
-       if (str_eq(conf->cpp_extension, "")) {
-               const char *p_language = p_language_for_language(actual_language);
-               free(conf->cpp_extension);
-               conf->cpp_extension = x_strdup(extension_for_language(p_language) + 1);
-       }
-
-       // Don't try to second guess the compilers heuristics for stdout handling.
-       if (output_obj && str_eq(output_obj, "-")) {
-               stats_update(STATS_OUTSTDOUT);
-               cc_log("Output file is -");
-               result = false;
-               goto out;
-       }
-
-       if (!output_obj) {
-               if (output_is_precompiled_header) {
-                       output_obj = format("%s.gch", input_file);
-               } else {
-                       char extension = found_S_opt ? 's' : 'o';
-                       output_obj = x_basename(input_file);
-                       char *p = strrchr(output_obj, '.');
-                       if (!p) {
-                               reformat(&output_obj, "%s.%c", output_obj, extension);
-                       } else if (!p[1]) {
-                               reformat(&output_obj, "%s%c", output_obj, extension);
-                       } else {
-                               p[1] = extension;
-                               p[2] = 0;
-                       }
-               }
-       }
-
-       if (seen_split_dwarf) {
-               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);
-       }
-
-       // 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)) {
-               cc_log("Not a regular file: %s", output_obj);
-               stats_update(STATS_BADOUTPUTFILE);
-               result = false;
-               goto out;
-       }
-
-       {
-               char *output_dir = x_dirname(output_obj);
-               if (stat(output_dir, &st) != 0 || !S_ISDIR(st.st_mode)) {
-                       cc_log("Directory does not exist: %s", output_dir);
-                       stats_update(STATS_BADOUTPUTFILE);
-                       result = false;
-                       free(output_dir);
-                       goto out;
-               }
-               free(output_dir);
-       }
-
-       // Some options shouldn't be passed to the real compiler when it compiles
-       // preprocessed code:
-       //
-       // -finput-charset=XXX (otherwise conversion happens twice)
-       // -x XXX (otherwise the wrong language is selected)
-       if (input_charset) {
-               args_add(cpp_args, input_charset);
-       }
-       if (found_pch) {
-               args_add(cpp_args, "-fpch-preprocess");
-       }
-       if (explicit_language) {
-               args_add(cpp_args, "-x");
-               args_add(cpp_args, explicit_language);
-       }
-
-       // Since output is redirected, compilers will not color their output by
-       // default, so force it explicitly if it would be otherwise done.
-       if (!found_color_diagnostics && color_output_possible()) {
-               if (guessed_compiler == GUESSED_CLANG) {
-                       if (!str_eq(actual_language, "assembler")) {
-                               args_add(common_args, "-fcolor-diagnostics");
-                               cc_log("Automatically enabling colors");
-                       }
-               } else if (guessed_compiler == GUESSED_GCC) {
-                       // GCC has it since 4.9, but that'd require detecting what GCC version is
-                       // used for the actual compile. However it requires also GCC_COLORS to be
-                       // set (and not empty), so use that for detecting if GCC would use
-                       // colors.
-                       if (getenv("GCC_COLORS") && getenv("GCC_COLORS")[0] != '\0') {
-                               args_add(common_args, "-fdiagnostics-color");
-                               cc_log("Automatically enabling colors");
-                       }
-               }
-       }
-
-       // Add flags for dependency generation only to the preprocessor command line.
-       if (generating_dependencies) {
-               if (!dependency_filename_specified) {
-                       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);
-                       output_dep = make_relative_path(x_strdup(default_depfile_name));
-               }
-
-               if (!dependency_target_specified
-                   && !dependency_implicit_target_specified
-                   && !str_eq(get_extension(output_dep), ".o")) {
-                       args_add(dep_args, "-MQ");
-                       args_add(dep_args, output_obj);
-               }
-       }
-       if (generating_coverage) {
-               char *base_name = remove_extension(output_obj);
-               char *default_covfile_name = format("%s.gcno", base_name);
-               free(base_name);
-               output_cov = make_relative_path(default_covfile_name);
-       }
-       if (generating_stackusage) {
-               char *base_name = remove_extension(output_obj);
-               char *default_sufile_name = format("%s.su", base_name);
-               free(base_name);
-               output_su = make_relative_path(default_sufile_name);
-       }
-
-       *compiler_args = args_copy(common_args);
-       args_extend(*compiler_args, compiler_only_args);
-
-       if (conf->run_second_cpp) {
-               args_extend(*compiler_args, cpp_args);
-       } else if (found_directives_only || found_rewrite_includes) {
-               // Need to pass the macros and any other preprocessor directives again.
-               args_extend(*compiler_args, cpp_args);
-               if (found_directives_only) {
-                       args_add(cpp_args, "-fdirectives-only");
-                       // The preprocessed source code still needs some more preprocessing.
-                       args_add(*compiler_args, "-fpreprocessed");
-                       args_add(*compiler_args, "-fdirectives-only");
-               }
-               if (found_rewrite_includes) {
-                       args_add(cpp_args, "-frewrite-includes");
-                       // The preprocessed source code still needs some more preprocessing.
-                       args_add(*compiler_args, "-x");
-                       args_add(*compiler_args, actual_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");
-       }
-
-       if (found_dc_opt) {
-               args_add(*compiler_args, "-dc");
-       }
-
-       for (size_t i = 0; i < arch_args_size; ++i) {
-               args_add(*compiler_args, "-arch");
-               args_add(*compiler_args, arch_args[i]);
-       }
-
-       // Only pass dependency arguments to the preprocessor since Intel's C++
-       // compiler doesn't produce a correct .d file when compiling preprocessed
-       // source.
-       args_extend(cpp_args, dep_args);
-
-       *preprocessor_args = args_copy(common_args);
-       args_extend(*preprocessor_args, cpp_args);
+  bool found_c_opt = false;
+  bool found_dc_opt = false;
+  bool found_S_opt = false;
+  bool found_pch = false;
+  bool found_fpch_preprocess = false;
+  const char* explicit_language = NULL; // As specified with -x.
+  const char* file_language;            // As deduced from file extension.
+  const char* input_charset = NULL;
+
+  // Is the dependency makefile name overridden with -MF?
+  bool dependency_filename_specified = false;
+
+  // Is the dependency makefile target name specified with -MT or -MQ?
+  bool dependency_target_specified = false;
+
+  // Is the dependency target name implicitly specified using
+  // DEPENDENCIES_OUTPUT or SUNPRO_DEPENDENCIES?
+  bool dependency_implicit_target_specified = false;
+
+  // 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 = args_copy(args);
+
+  // common_args contains all original arguments except:
+  // * those that never should be passed to the preprocessor,
+  // * those that only should be passed to the preprocessor (if run_second_cpp
+  //   is false), and
+  // * dependency options (like -MD and friends).
+  struct args* common_args = args_init(0, NULL);
+
+  // cpp_args contains arguments that were not added to common_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 = args_init(0, NULL);
+
+  // dep_args contains dependency options like -MD. They are only passed to the
+  // preprocessor, never to the compiler.
+  struct args* dep_args = args_init(0, NULL);
+
+  // compiler_only_args contains arguments that should only be passed to the
+  // compiler, not the preprocessor.
+  struct args* compiler_only_args = args_init(0, NULL);
+
+  bool found_color_diagnostics = false;
+  bool found_directives_only = false;
+  bool found_rewrite_includes = false;
+
+  int argc = expanded_args->argc;
+  char** argv = expanded_args->argv;
+  args_add(common_args, argv[0]);
+
+  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++;
+      if (i == argc) {
+        cc_log("--ccache-skip lacks an argument");
+        result = false;
+        goto out;
+      }
+      args_add(common_args, argv[i]);
+      continue;
+    }
+
+    // Special case for -E.
+    if (str_eq(argv[i], "-E")) {
+      stats_update(STATS_PREPROCESSING);
+      result = false;
+      goto out;
+    }
+
+    // Handle "@file" argument.
+    if (str_startswith(argv[i], "@") || str_startswith(argv[i], "-@")) {
+      char* argpath = argv[i] + 1;
+
+      if (argpath[-1] == '-') {
+        ++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);
+        result = false;
+        goto out;
+      }
+
+      args_insert(expanded_args, i, file_args, true);
+      argc = expanded_args->argc;
+      argv = expanded_args->argv;
+      i--;
+      continue;
+    }
+
+    // Handle cuda "-optf" and "--options-file" argument.
+    if (guessed_compiler == GUESSED_NVCC
+        && (str_eq(argv[i], "-optf") || str_eq(argv[i], "--options-file"))) {
+      if (i == argc - 1) {
+        cc_log("Expected argument after %s", argv[i]);
+        stats_update(STATS_ARGS);
+        result = false;
+        goto out;
+      }
+      ++i;
+
+      // Argument is a comma-separated list of files.
+      char* str_start = argv[i];
+      char* str_end = strchr(str_start, ',');
+      int index = i + 1;
+
+      if (!str_end) {
+        str_end = str_start + strlen(str_start);
+      }
+
+      while (str_end) {
+        *str_end = '\0';
+        struct args* file_args = args_init_from_gcc_atfile(str_start);
+        if (!file_args) {
+          cc_log("Couldn't read cuda options file %s", str_start);
+          stats_update(STATS_ARGS);
+          result = false;
+          goto out;
+        }
+
+        int new_index = file_args->argc + index;
+        args_insert(expanded_args, index, file_args, false);
+        index = new_index;
+        str_start = str_end;
+        str_end = strchr(str_start, ',');
+      }
+
+      argc = expanded_args->argc;
+      argv = expanded_args->argv;
+      continue;
+    }
+
+    // These are always too hard.
+    if (compopt_too_hard(argv[i]) || str_startswith(argv[i], "-fdump-")) {
+      cc_log("Compiler option %s is unsupported", argv[i]);
+      stats_update(STATS_UNSUPPORTED_OPTION);
+      result = false;
+      goto out;
+    }
+
+    // These are too hard in direct mode.
+    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.
+    if (str_startswith(argv[i], "-Xarch_")) {
+      cc_log("Unsupported compiler option :%s", argv[i]);
+      stats_update(STATS_UNSUPPORTED_OPTION);
+      result = false;
+      goto out;
+    }
+
+    // Handle -arch options.
+    if (str_eq(argv[i], "-arch")) {
+      if (arch_args_size == MAX_ARCH_ARGS - 1) {
+        cc_log("Too many -arch compiler options; ccache supports at most %d",
+               MAX_ARCH_ARGS);
+        stats_update(STATS_UNSUPPORTED_OPTION);
+        result = false;
+        goto out;
+      }
+
+      ++i;
+      arch_args[arch_args_size] = x_strdup(argv[i]); // It will leak.
+      ++arch_args_size;
+      if (arch_args_size == 2) {
+        conf->run_second_cpp = true;
+      }
+      continue;
+    }
+
+    // Handle options that should not be passed to the preprocessor.
+    if (compopt_affects_comp(argv[i])) {
+      args_add(compiler_only_args, argv[i]);
+      if (compopt_takes_arg(argv[i])) {
+        if (i == argc - 1) {
+          cc_log("Missing argument to %s", argv[i]);
+          stats_update(STATS_ARGS);
+          result = false;
+          goto out;
+        }
+        args_add(compiler_only_args, argv[i + 1]);
+        ++i;
+      }
+      continue;
+    }
+    if (compopt_prefix_affects_comp(argv[i])) {
+      args_add(compiler_only_args, argv[i]);
+      continue;
+    }
+
+    if (str_eq(argv[i], "-fpch-preprocess") || str_eq(argv[i], "-emit-pch")
+        || str_eq(argv[i], "-emit-pth")) {
+      found_fpch_preprocess = true;
+    }
+
+    // We must have -c.
+    if (str_eq(argv[i], "-c")) {
+      found_c_opt = true;
+      continue;
+    }
+
+    // when using nvcc with separable compilation, -dc implies -c
+    if ((str_eq(argv[i], "-dc") || str_eq(argv[i], "--device-c"))
+        && guessed_compiler == GUESSED_NVCC) {
+      found_dc_opt = true;
+      continue;
+    }
+
+    // -S changes the default extension.
+    if (str_eq(argv[i], "-S")) {
+      args_add(common_args, argv[i]);
+      found_S_opt = true;
+      continue;
+    }
+
+    // Special handling for -x: remember the last specified language before the
+    // input file and strip all -x options from the arguments.
+    if (str_eq(argv[i], "-x")) {
+      if (i == argc - 1) {
+        cc_log("Missing argument to %s", argv[i]);
+        stats_update(STATS_ARGS);
+        result = false;
+        goto out;
+      }
+      if (!input_file) {
+        explicit_language = argv[i + 1];
+      }
+      i++;
+      continue;
+    }
+    if (str_startswith(argv[i], "-x")) {
+      if (!input_file) {
+        explicit_language = &argv[i][2];
+      }
+      continue;
+    }
+
+    // We need to work out where the output was meant to go.
+    if (str_eq(argv[i], "-o")) {
+      if (i == argc - 1) {
+        cc_log("Missing argument to %s", argv[i]);
+        stats_update(STATS_ARGS);
+        result = false;
+        goto out;
+      }
+      output_obj = make_relative_path(x_strdup(argv[i + 1]));
+      i++;
+      continue;
+    }
+
+    // Alternate form of -o with no space. Nvcc does not support this.
+    if (str_startswith(argv[i], "-o") && guessed_compiler != GUESSED_NVCC) {
+      output_obj = make_relative_path(x_strdup(&argv[i][2]));
+      continue;
+    }
+
+    if (str_startswith(argv[i], "-fdebug-prefix-map=")
+        || str_startswith(argv[i], "-ffile-prefix-map=")) {
+      debug_prefix_maps = static_cast<char**>(x_realloc(
+        debug_prefix_maps, (debug_prefix_maps_len + 1) * sizeof(char*)));
+      debug_prefix_maps[debug_prefix_maps_len++] =
+        x_strdup(&argv[i][argv[i][2] == 'f' ? 18 : 19]);
+      args_add(common_args, argv[i]);
+      continue;
+    }
+
+    // Debugging is handled specially, so that we know if we can strip line
+    // number info.
+    if (str_startswith(argv[i], "-g")) {
+      args_add(common_args, argv[i]);
+
+      if (str_startswith(argv[i], "-gdwarf")) {
+        // Selection of DWARF format (-gdwarf or -gdwarf-<version>) enables
+        // debug info on level 2.
+        generating_debuginfo = true;
+        continue;
+      }
+
+      char last_char = argv[i][strlen(argv[i]) - 1];
+      if (last_char == '0') {
+        // "-g0", "-ggdb0" or similar: All debug information disabled.
+        generating_debuginfo = false;
+        generating_debuginfo_level_3 = false;
+      } else {
+        generating_debuginfo = true;
+        if (last_char == '3') {
+          generating_debuginfo_level_3 = true;
+        }
+        if (str_eq(argv[i], "-gsplit-dwarf")) {
+          seen_split_dwarf = true;
+        }
+      }
+      continue;
+    }
+
+    // These options require special handling, because they behave differently
+    // with gcc -E, when the output file is not specified.
+    if (str_eq(argv[i], "-MD") || str_eq(argv[i], "-MMD")) {
+      generating_dependencies = true;
+      args_add(dep_args, argv[i]);
+      continue;
+    }
+    if (str_startswith(argv[i], "-MF")) {
+      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) {
+          cc_log("Missing argument to %s", argv[i]);
+          stats_update(STATS_ARGS);
+          result = false;
+          goto out;
+        }
+        arg = argv[i + 1];
+        i++;
+      } else {
+        // -MFarg
+        arg = &argv[i][3];
+      }
+      output_dep = make_relative_path(x_strdup(arg));
+      // Keep the format of the args the same.
+      if (separate_argument) {
+        args_add(dep_args, "-MF");
+        args_add(dep_args, output_dep);
+      } else {
+        char* option = format("-MF%s", output_dep);
+        args_add(dep_args, option);
+        free(option);
+      }
+      continue;
+    }
+    if (str_startswith(argv[i], "-MQ") || str_startswith(argv[i], "-MT")) {
+      dependency_target_specified = true;
+
+      char* relpath;
+      if (strlen(argv[i]) == 3) {
+        // -MQ arg or -MT arg
+        if (i == argc - 1) {
+          cc_log("Missing argument to %s", argv[i]);
+          stats_update(STATS_ARGS);
+          result = false;
+          goto out;
+        }
+        args_add(dep_args, argv[i]);
+        relpath = make_relative_path(x_strdup(argv[i + 1]));
+        args_add(dep_args, relpath);
+        free(relpath);
+        i++;
+      } else {
+        char* arg_opt = x_strndup(argv[i], 3);
+        relpath = make_relative_path(x_strdup(argv[i] + 3));
+        char* option = format("%s%s", arg_opt, relpath);
+        args_add(dep_args, option);
+        free(arg_opt);
+        free(relpath);
+        free(option);
+      }
+      continue;
+    }
+    if (str_eq(argv[i], "-fprofile-arcs")) {
+      profile_arcs = true;
+      args_add(common_args, argv[i]);
+      continue;
+    }
+    if (str_eq(argv[i], "-ftest-coverage")) {
+      generating_coverage = true;
+      args_add(common_args, argv[i]);
+      continue;
+    }
+    if (str_eq(argv[i], "-fstack-usage")) {
+      generating_stackusage = true;
+      args_add(common_args, argv[i]);
+      continue;
+    }
+    if (str_eq(argv[i], "--coverage")      // = -fprofile-arcs -ftest-coverage
+        || str_eq(argv[i], "-coverage")) { // Undocumented but still works.
+      profile_arcs = true;
+      generating_coverage = true;
+      args_add(common_args, argv[i]);
+      continue;
+    }
+    if (str_startswith(argv[i], "-fprofile-dir=")) {
+      profile_dir = x_strdup(argv[i] + 14);
+      args_add(common_args, argv[i]);
+      continue;
+    }
+    if (str_startswith(argv[i], "-fsanitize-blacklist=")) {
+      sanitize_blacklists = static_cast<char**>(x_realloc(
+        sanitize_blacklists, (sanitize_blacklists_len + 1) * sizeof(char*)));
+      sanitize_blacklists[sanitize_blacklists_len++] = x_strdup(argv[i] + 21);
+      args_add(common_args, argv[i]);
+      continue;
+    }
+    if (str_startswith(argv[i], "--sysroot=")) {
+      char* relpath = make_relative_path(x_strdup(argv[i] + 10));
+      char* option = format("--sysroot=%s", relpath);
+      args_add(common_args, option);
+      free(relpath);
+      free(option);
+      continue;
+    }
+    // Alternate form of specifying sysroot without =
+    if (str_eq(argv[i], "--sysroot")) {
+      if (i == argc - 1) {
+        cc_log("Missing argument to %s", argv[i]);
+        stats_update(STATS_ARGS);
+        result = false;
+        goto out;
+      }
+      args_add(common_args, argv[i]);
+      char* relpath = make_relative_path(x_strdup(argv[i + 1]));
+      args_add(common_args, relpath);
+      i++;
+      free(relpath);
+      continue;
+    }
+    // Alternate form of specifying target without =
+    if (str_eq(argv[i], "-target")) {
+      if (i == argc - 1) {
+        cc_log("Missing argument to %s", argv[i]);
+        stats_update(STATS_ARGS);
+        result = false;
+        goto out;
+      }
+      args_add(common_args, argv[i]);
+      args_add(common_args, argv[i + 1]);
+      i++;
+      continue;
+    }
+    if (str_startswith(argv[i], "-Wp,")) {
+      if (str_eq(argv[i], "-Wp,-P") || strstr(argv[i], ",-P,")
+          || str_endswith(argv[i], ",-P")) {
+        // -P removes preprocessor information in such a way that the object
+        // file from compiling the preprocessed file will not be equal to the
+        // object file produced when compiling without ccache.
+        cc_log("Too hard option -Wp,-P detected");
+        stats_update(STATS_UNSUPPORTED_OPTION);
+        failed();
+      } else if (str_startswith(argv[i], "-Wp,-MD,")
+                 && !strchr(argv[i] + 8, ',')) {
+        generating_dependencies = true;
+        dependency_filename_specified = true;
+        free(output_dep);
+        output_dep = make_relative_path(x_strdup(argv[i] + 8));
+        args_add(dep_args, argv[i]);
+        continue;
+      } else if (str_startswith(argv[i], "-Wp,-MMD,")
+                 && !strchr(argv[i] + 9, ',')) {
+        generating_dependencies = true;
+        dependency_filename_specified = true;
+        free(output_dep);
+        output_dep = make_relative_path(x_strdup(argv[i] + 9));
+        args_add(dep_args, argv[i]);
+        continue;
+      } else if (str_startswith(argv[i], "-Wp,-D")
+                 && !strchr(argv[i] + 6, ',')) {
+        // Treat it like -D.
+        args_add(cpp_args, argv[i] + 4);
+        continue;
+      } else if (str_eq(argv[i], "-Wp,-MP")
+                 || (strlen(argv[i]) > 8 && str_startswith(argv[i], "-Wp,-M")
+                     && argv[i][7] == ','
+                     && (argv[i][6] == 'F' || argv[i][6] == 'Q'
+                         || argv[i][6] == 'T')
+                     && !strchr(argv[i] + 8, ','))) {
+        // TODO: Make argument to MF/MQ/MT relative.
+        args_add(dep_args, argv[i]);
+        continue;
+      } else if (conf->direct_mode) {
+        // -Wp, can be used to pass too hard options to the preprocessor.
+        // Hence, disable direct mode.
+        cc_log("Unsupported compiler option for direct mode: %s", argv[i]);
+        conf->direct_mode = false;
+      }
+
+      // Any other -Wp,* arguments are only relevant for the preprocessor.
+      args_add(cpp_args, argv[i]);
+      continue;
+    }
+    if (str_eq(argv[i], "-MP")) {
+      args_add(dep_args, argv[i]);
+      continue;
+    }
+
+    // Input charset needs to be handled specially.
+    if (str_startswith(argv[i], "-finput-charset=")) {
+      input_charset = argv[i];
+      continue;
+    }
+
+    if (str_eq(argv[i], "--serialize-diagnostics")) {
+      if (i == argc - 1) {
+        cc_log("Missing argument to %s", argv[i]);
+        stats_update(STATS_ARGS);
+        result = false;
+        goto out;
+      }
+      generating_diagnostics = true;
+      output_dia = make_relative_path(x_strdup(argv[i + 1]));
+      i++;
+      continue;
+    }
+
+    if (str_startswith(argv[i], "-fprofile-")) {
+      char* arg = x_strdup(argv[i]);
+      const char* arg_profile_dir = strchr(argv[i], '=');
+      if (arg_profile_dir) {
+        // Convert to absolute path.
+        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;
+        supported_profile_option = true;
+      } else if (str_startswith(argv[i], "-fprofile-use")
+                 || str_eq(argv[i], "-fbranch-probabilities")) {
+        profile_use = true;
+        supported_profile_option = true;
+      } else if (str_eq(argv[i], "-fprofile-dir")) {
+        supported_profile_option = true;
+      }
+
+      if (supported_profile_option) {
+        args_add(common_args, arg);
+        free(arg);
+
+        // If the profile directory has already been set, give up... Hard to
+        // know what the user means, and what the compiler will do.
+        if (arg_profile_dir && profile_dir) {
+          cc_log("Profile directory already set; giving up");
+          result = false;
+          goto out;
+        } else if (arg_profile_dir) {
+          cc_log("Setting profile directory to %s", arg_profile_dir);
+          profile_dir = x_strdup(arg_profile_dir);
+        }
+        continue;
+      }
+      cc_log("Unknown profile option: %s", argv[i]);
+      free(arg);
+    }
+
+    if (str_eq(argv[i], "-fcolor-diagnostics")
+        || str_eq(argv[i], "-fno-color-diagnostics")
+        || str_eq(argv[i], "-fdiagnostics-color")
+        || str_eq(argv[i], "-fdiagnostics-color=always")
+        || str_eq(argv[i], "-fno-diagnostics-color")
+        || str_eq(argv[i], "-fdiagnostics-color=never")) {
+      args_add(common_args, argv[i]);
+      found_color_diagnostics = true;
+      continue;
+    }
+    if (str_eq(argv[i], "-fdiagnostics-color=auto")) {
+      if (color_output_possible()) {
+        // Output is redirected, so color output must be forced.
+        args_add(common_args, "-fdiagnostics-color=always");
+        cc_log("Automatically forcing colors");
+      } else {
+        args_add(common_args, argv[i]);
+      }
+      found_color_diagnostics = true;
+      continue;
+    }
+
+    // GCC
+    if (str_eq(argv[i], "-fdirectives-only")) {
+      found_directives_only = true;
+      continue;
+    }
+    // Clang
+    if (str_eq(argv[i], "-frewrite-includes")) {
+      found_rewrite_includes = true;
+      continue;
+    }
+
+    if (conf->sloppiness & SLOPPY_CLANG_INDEX_STORE
+        && str_eq(argv[i], "-index-store-path")) {
+      // Xcode 9 or later calls Clang with this option. The given path includes
+      // a UUID that might lead to cache misses, especially when cache is
+      // shared among multiple users.
+      i++;
+      if (i <= argc - 1) {
+        cc_log("Skipping argument -index-store-path %s", argv[i]);
+      }
+      continue;
+    }
+
+    // Options taking an argument that we may want to rewrite to relative paths
+    // 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])) {
+      if (i == argc - 1) {
+        cc_log("Missing argument to %s", argv[i]);
+        stats_update(STATS_ARGS);
+        result = false;
+        goto out;
+      }
+
+      if (!detect_pch(argv[i], argv[i + 1], &found_pch)) {
+        result = false;
+        goto out;
+      }
+
+      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);
+      } else {
+        args_add(common_args, argv[i]);
+        args_add(common_args, relpath);
+      }
+      free(relpath);
+
+      i++;
+      continue;
+    }
+
+    // Same as above but options with concatenated argument beginning with a
+    // slash.
+    if (argv[i][0] == '-') {
+      char* slash_pos = strchr(argv[i], '/');
+      if (slash_pos) {
+        char* option = x_strndup(argv[i], slash_pos - argv[i]);
+        if (compopt_takes_concat_arg(option) && compopt_takes_path(option)) {
+          char* relpath = make_relative_path(x_strdup(slash_pos));
+          char* new_option = format("%s%s", option, relpath);
+          if (compopt_affects_cpp(option)) {
+            args_add(cpp_args, new_option);
+          } else {
+            args_add(common_args, new_option);
+          }
+          free(new_option);
+          free(relpath);
+          free(option);
+          continue;
+        } else {
+          free(option);
+        }
+      }
+    }
+
+    // Options that take an argument.
+    if (compopt_takes_arg(argv[i])) {
+      if (i == argc - 1) {
+        cc_log("Missing argument to %s", argv[i]);
+        stats_update(STATS_ARGS);
+        result = false;
+        goto out;
+      }
+
+      if (compopt_affects_cpp(argv[i])) {
+        args_add(cpp_args, argv[i]);
+        args_add(cpp_args, argv[i + 1]);
+      } else {
+        args_add(common_args, argv[i]);
+        args_add(common_args, argv[i + 1]);
+      }
+
+      i++;
+      continue;
+    }
+
+    // Other options.
+    if (argv[i][0] == '-') {
+      if (compopt_affects_cpp(argv[i]) || compopt_prefix_affects_cpp(argv[i])) {
+        args_add(cpp_args, argv[i]);
+      } else {
+        args_add(common_args, argv[i]);
+      }
+      continue;
+    }
+
+    // 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.
+    //
+    // Note that "/dev/null" is an exception that is sometimes used as an input
+    // file when code is testing compiler flags.
+    struct stat st;
+    if (!str_eq(argv[i], "/dev/null")
+        && (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]);
+      args_add(common_args, argv[i]);
+      continue;
+    }
+
+    if (input_file) {
+      if (language_for_file(argv[i])) {
+        cc_log("Multiple input files: %s and %s", input_file, argv[i]);
+        stats_update(STATS_MULTIPLE);
+      } else if (!found_c_opt && !found_dc_opt) {
+        cc_log("Called for link with %s", argv[i]);
+        if (strstr(argv[i], "conftest.")) {
+          stats_update(STATS_CONFTEST);
+        } else {
+          stats_update(STATS_LINK);
+        }
+      } else {
+        cc_log("Unsupported source extension: %s", argv[i]);
+        stats_update(STATS_SOURCELANG);
+      }
+      result = false;
+      goto out;
+    }
+
+    // The source code file path gets put into the notes.
+    if (generating_coverage) {
+      input_file = x_strdup(argv[i]);
+      continue;
+    }
+
+    if (is_symlink(argv[i])) {
+      // Don't rewrite source file path if it's a symlink since
+      // make_relative_path resolves symlinks using realpath(3) and this leads
+      // to potentially choosing incorrect relative header files. See the
+      // "symlink to source file" test.
+      input_file = x_strdup(argv[i]);
+    } else {
+      // Rewrite to relative to increase hit rate.
+      input_file = make_relative_path(x_strdup(argv[i]));
+    }
+  } // for
+
+  if (generating_debuginfo && conf->unify) {
+    cc_log("Generating debug info; disabling unify mode");
+    conf->unify = false;
+  }
+
+  if (generating_debuginfo_level_3 && !conf->run_second_cpp) {
+    cc_log("Generating debug info level 3; not compiling preprocessed code");
+    conf->run_second_cpp = true;
+  }
+
+  // See <http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html>.
+  // Contrary to what the documentation seems to imply the compiler still
+  // creates object files with these defined (confirmed with GCC 8.2.1), i.e.
+  // they work as -MMD/-MD, not -MM/-M. These environment variables do nothing
+  // on Clang.
+  {
+    char* dependencies_env = getenv("DEPENDENCIES_OUTPUT");
+    bool using_sunpro_dependencies = false;
+    if (!dependencies_env) {
+      dependencies_env = getenv("SUNPRO_DEPENDENCIES");
+      using_sunpro_dependencies = true;
+    }
+    if (dependencies_env) {
+      generating_dependencies = true;
+      dependency_filename_specified = true;
+      char* saveptr = nullptr;
+      char* abspath_file = strtok_r(dependencies_env, " ", &saveptr);
+
+      free(output_dep);
+      output_dep = make_relative_path(x_strdup(abspath_file));
+
+      // specifying target object is optional.
+      char* abspath_obj = strtok_r(nullptr, " ", &saveptr);
+      if (abspath_obj) {
+        // it's the "file target" form.
+
+        dependency_target_specified = true;
+        char* relpath_obj = make_relative_path(x_strdup(abspath_obj));
+        // ensure compiler gets relative path.
+        char* relpath_both = format("%s %s", output_dep, relpath_obj);
+        if (using_sunpro_dependencies) {
+          x_setenv("SUNPRO_DEPENDENCIES", relpath_both);
+        } else {
+          x_setenv("DEPENDENCIES_OUTPUT", relpath_both);
+        }
+        free(relpath_obj);
+        free(relpath_both);
+      } else {
+        // it's the "file" form.
+
+        dependency_implicit_target_specified = true;
+        // ensure compiler gets relative path.
+        if (using_sunpro_dependencies) {
+          x_setenv("SUNPRO_DEPENDENCIES", output_dep);
+        } else {
+          x_setenv("DEPENDENCIES_OUTPUT", output_dep);
+        }
+      }
+    }
+  }
+
+  if (!input_file) {
+    cc_log("No input file found");
+    stats_update(STATS_NOINPUT);
+    result = false;
+    goto out;
+  }
+
+  if (found_pch || found_fpch_preprocess) {
+    using_precompiled_header = true;
+    if (!(conf->sloppiness & SLOPPY_TIME_MACROS)) {
+      cc_log(
+        "You have to specify \"time_macros\" sloppiness when using"
+        " precompiled headers to get direct hits");
+      cc_log("Disabling direct mode");
+      stats_update(STATS_CANTUSEPCH);
+      result = false;
+      goto out;
+    }
+  }
+
+  if (explicit_language && str_eq(explicit_language, "none")) {
+    explicit_language = NULL;
+  }
+  file_language = language_for_file(input_file);
+  if (explicit_language) {
+    if (!language_is_supported(explicit_language)) {
+      cc_log("Unsupported language: %s", explicit_language);
+      stats_update(STATS_SOURCELANG);
+      result = false;
+      goto out;
+    }
+    actual_language = x_strdup(explicit_language);
+  } else {
+    actual_language = file_language;
+  }
+
+  output_is_precompiled_header =
+    actual_language && strstr(actual_language, "-header");
+
+  if (output_is_precompiled_header
+      && !(conf->sloppiness & SLOPPY_PCH_DEFINES)) {
+    cc_log(
+      "You have to specify \"pch_defines,time_macros\" sloppiness when"
+      " creating precompiled headers");
+    stats_update(STATS_CANTUSEPCH);
+    result = false;
+    goto out;
+  }
+
+  if (!found_c_opt && !found_dc_opt && !found_S_opt) {
+    if (output_is_precompiled_header) {
+      args_add(common_args, "-c");
+    } else {
+      cc_log("No -c option found");
+      // I find that having a separate statistic for autoconf tests is useful,
+      // as they are the dominant form of "called for link" in many cases.
+      if (strstr(input_file, "conftest.")) {
+        stats_update(STATS_CONFTEST);
+      } else {
+        stats_update(STATS_LINK);
+      }
+      result = false;
+      goto out;
+    }
+  }
+
+  if (!actual_language) {
+    cc_log("Unsupported source extension: %s", input_file);
+    stats_update(STATS_SOURCELANG);
+    result = false;
+    goto out;
+  }
+
+  if (!conf->run_second_cpp && str_eq(actual_language, "cu")) {
+    cc_log("Using CUDA compiler; not compiling preprocessed code");
+    conf->run_second_cpp = true;
+  }
+
+  direct_i_file = language_is_preprocessed(actual_language);
+
+  if (output_is_precompiled_header && !conf->run_second_cpp) {
+    // It doesn't work to create the .gch from preprocessed source.
+    cc_log("Creating precompiled header; not compiling preprocessed code");
+    conf->run_second_cpp = true;
+  }
+
+  if (str_eq(conf->cpp_extension, "")) {
+    const char* p_language = p_language_for_language(actual_language);
+    free(conf->cpp_extension);
+    conf->cpp_extension = x_strdup(extension_for_language(p_language) + 1);
+  }
+
+  // Don't try to second guess the compilers heuristics for stdout handling.
+  if (output_obj && str_eq(output_obj, "-")) {
+    stats_update(STATS_OUTSTDOUT);
+    cc_log("Output file is -");
+    result = false;
+    goto out;
+  }
+
+  if (!output_obj) {
+    if (output_is_precompiled_header) {
+      output_obj = format("%s.gch", input_file);
+    } else {
+      char extension = found_S_opt ? 's' : 'o';
+      output_obj = x_basename(input_file);
+      char* p = strrchr(output_obj, '.');
+      if (!p) {
+        reformat(&output_obj, "%s.%c", output_obj, extension);
+      } else if (!p[1]) {
+        reformat(&output_obj, "%s%c", output_obj, extension);
+      } else {
+        p[1] = extension;
+        p[2] = 0;
+      }
+    }
+  }
+
+  if (seen_split_dwarf) {
+    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);
+  }
+
+  // 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)) {
+    cc_log("Not a regular file: %s", output_obj);
+    stats_update(STATS_BADOUTPUTFILE);
+    result = false;
+    goto out;
+  }
+
+  {
+    char* output_dir = x_dirname(output_obj);
+    if (stat(output_dir, &st) != 0 || !S_ISDIR(st.st_mode)) {
+      cc_log("Directory does not exist: %s", output_dir);
+      stats_update(STATS_BADOUTPUTFILE);
+      result = false;
+      free(output_dir);
+      goto out;
+    }
+    free(output_dir);
+  }
+
+  // Some options shouldn't be passed to the real compiler when it compiles
+  // preprocessed code:
+  //
+  // -finput-charset=XXX (otherwise conversion happens twice)
+  // -x XXX (otherwise the wrong language is selected)
+  if (input_charset) {
+    args_add(cpp_args, input_charset);
+  }
+  if (found_pch) {
+    args_add(cpp_args, "-fpch-preprocess");
+  }
+  if (explicit_language) {
+    args_add(cpp_args, "-x");
+    args_add(cpp_args, explicit_language);
+  }
+
+  // Since output is redirected, compilers will not color their output by
+  // default, so force it explicitly if it would be otherwise done.
+  if (!found_color_diagnostics && color_output_possible()) {
+    if (guessed_compiler == GUESSED_CLANG) {
+      if (!str_eq(actual_language, "assembler")) {
+        args_add(common_args, "-fcolor-diagnostics");
+        cc_log("Automatically enabling colors");
+      }
+    } else if (guessed_compiler == GUESSED_GCC) {
+      // GCC has it since 4.9, but that'd require detecting what GCC version is
+      // used for the actual compile. However it requires also GCC_COLORS to be
+      // set (and not empty), so use that for detecting if GCC would use
+      // colors.
+      if (getenv("GCC_COLORS") && getenv("GCC_COLORS")[0] != '\0') {
+        args_add(common_args, "-fdiagnostics-color");
+        cc_log("Automatically enabling colors");
+      }
+    }
+  }
+
+  // Add flags for dependency generation only to the preprocessor command line.
+  if (generating_dependencies) {
+    if (!dependency_filename_specified) {
+      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);
+      output_dep = make_relative_path(x_strdup(default_depfile_name));
+    }
+
+    if (!dependency_target_specified && !dependency_implicit_target_specified
+        && !str_eq(get_extension(output_dep), ".o")) {
+      args_add(dep_args, "-MQ");
+      args_add(dep_args, output_obj);
+    }
+  }
+  if (generating_coverage) {
+    char* base_name = remove_extension(output_obj);
+    char* default_covfile_name = format("%s.gcno", base_name);
+    free(base_name);
+    output_cov = make_relative_path(default_covfile_name);
+  }
+  if (generating_stackusage) {
+    char* base_name = remove_extension(output_obj);
+    char* default_sufile_name = format("%s.su", base_name);
+    free(base_name);
+    output_su = make_relative_path(default_sufile_name);
+  }
+
+  *compiler_args = args_copy(common_args);
+  args_extend(*compiler_args, compiler_only_args);
+
+  if (conf->run_second_cpp) {
+    args_extend(*compiler_args, cpp_args);
+  } else if (found_directives_only || found_rewrite_includes) {
+    // Need to pass the macros and any other preprocessor directives again.
+    args_extend(*compiler_args, cpp_args);
+    if (found_directives_only) {
+      args_add(cpp_args, "-fdirectives-only");
+      // The preprocessed source code still needs some more preprocessing.
+      args_add(*compiler_args, "-fpreprocessed");
+      args_add(*compiler_args, "-fdirectives-only");
+    }
+    if (found_rewrite_includes) {
+      args_add(cpp_args, "-frewrite-includes");
+      // The preprocessed source code still needs some more preprocessing.
+      args_add(*compiler_args, "-x");
+      args_add(*compiler_args, actual_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");
+  }
+
+  if (found_dc_opt) {
+    args_add(*compiler_args, "-dc");
+  }
+
+  for (size_t i = 0; i < arch_args_size; ++i) {
+    args_add(*compiler_args, "-arch");
+    args_add(*compiler_args, arch_args[i]);
+  }
+
+  // Only pass dependency arguments to the preprocessor since Intel's C++
+  // compiler doesn't produce a correct .d file when compiling preprocessed
+  // source.
+  args_extend(cpp_args, dep_args);
+
+  *preprocessor_args = args_copy(common_args);
+  args_extend(*preprocessor_args, cpp_args);
 
 out:
-       args_free(expanded_args);
-       args_free(common_args);
-       args_free(dep_args);
-       args_free(cpp_args);
-       return result;
+  args_free(expanded_args);
+  args_free(common_args);
+  args_free(dep_args);
+  args_free(cpp_args);
+  return result;
 }
 
 static void
-create_initial_config_file(const char *path)
+create_initial_config_file(const charpath)
 {
-       if (create_parent_dirs(path) != 0) {
-               return;
-       }
-
-       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.
-               max_files *= 16;
-               max_size *= 16;
-       } else {
-               max_files = 0;
-               max_size = conf->max_size;
-       }
-       free(stats_dir);
-
-       FILE *f = fopen(path, "w");
-       if (!f) {
-               return;
-       }
-       if (max_files != 0) {
-               fprintf(f, "max_files = %u\n", max_files);
-               conf->max_files = max_files;
-       }
-       if (max_size != 0) {
-               char *size = format_parsable_size_with_suffix(max_size);
-               fprintf(f, "max_size = %s\n", size);
-               free(size);
-               conf->max_size = max_size;
-       }
-       fclose(f);
+  if (create_parent_dirs(path) != 0) {
+    return;
+  }
+
+  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.
+    max_files *= 16;
+    max_size *= 16;
+  } else {
+    max_files = 0;
+    max_size = conf->max_size;
+  }
+  free(stats_dir);
+
+  FILE* f = fopen(path, "w");
+  if (!f) {
+    return;
+  }
+  if (max_files != 0) {
+    fprintf(f, "max_files = %u\n", max_files);
+    conf->max_files = max_files;
+  }
+  if (max_size != 0) {
+    char* size = format_parsable_size_with_suffix(max_size);
+    fprintf(f, "max_size = %s\n", size);
+    free(size);
+    conf->max_size = max_size;
+  }
+  fclose(f);
 }
 
 #ifdef MTR_ENABLED
-static void *trace_id;
-static char *tmp_trace_file;
+static voidtrace_id;
+static chartmp_trace_file;
 
 static void
-trace_init(char *path)
+trace_init(charpath)
 {
-       tmp_trace_file = path;
-       mtr_init(tmp_trace_file);
-       char *s = format("%f", time_seconds());
-       MTR_INSTANT_C("", "", "time", s);
+  tmp_trace_file = path;
+  mtr_init(tmp_trace_file);
+  char* s = format("%f", time_seconds());
+  MTR_INSTANT_C("", "", "time", s);
 }
 
 static void
 trace_start(void)
 {
-       MTR_META_PROCESS_NAME(MYNAME);
-       trace_id = (void *) ((long) getpid());
-       MTR_START("program", "ccache", trace_id);
+  MTR_META_PROCESS_NAME(MYNAME);
+  trace_id = (void*)((long)getpid());
+  MTR_START("program", "ccache", trace_id);
 }
 
 static void
 trace_stop(void)
 {
-       char *trace_file = format("%s.ccache-trace", output_obj);
-       MTR_FINISH("program", "ccache", trace_id);
-       mtr_flush();
-       mtr_shutdown();
-       move_file(tmp_trace_file, trace_file);
-       free(trace_file);
-       free(tmp_trace_file);
+  char* trace_file = format("%s.ccache-trace", output_obj);
+  MTR_FINISH("program", "ccache", trace_id);
+  mtr_flush();
+  mtr_shutdown();
+  move_file(tmp_trace_file, trace_file);
+  free(trace_file);
+  free(tmp_trace_file);
 }
 
-static const char *
+static const char*
 tmpdir()
 {
-#ifndef _WIN32
-       const char *tmpdir = getenv("TMPDIR");
-       if (tmpdir != NULL) {
-               return tmpdir;
-       }
-#else
-       static char dirbuf[PATH_MAX];
-       DWORD retval = GetTempPath(PATH_MAX, dirbuf);
-       if (retval > 0 && retval < PATH_MAX) {
-               return dirbuf;
-       }
-#endif
-       return "/tmp";
+#  ifndef _WIN32
+  const char* tmpdir = getenv("TMPDIR");
+  if (tmpdir != NULL) {
+    return tmpdir;
+  }
+#  else
+  static char dirbuf[PATH_MAX];
+  DWORD retval = GetTempPath(PATH_MAX, dirbuf);
+  if (retval > 0 && retval < PATH_MAX) {
+    return dirbuf;
+  }
+#  endif
+  return "/tmp";
 }
 
 #endif // MTR_ENABLED
@@ -3498,153 +3502,177 @@ tmpdir()
 static void
 initialize(void)
 {
-       bool enable_internal_trace = getenv("CCACHE_INTERNAL_TRACE");
-       if (enable_internal_trace) {
+  bool enable_internal_trace = getenv("CCACHE_INTERNAL_TRACE");
+  if (enable_internal_trace) {
 #ifdef MTR_ENABLED
-               // We don't have any conf yet, so we can't use temp_dir() here.
-               trace_init(format("%s/tmp.ccache-trace.%d", tmpdir(), (int)getpid()));
+    // We don't have any conf yet, so we can't use temp_dir() here.
+    trace_init(format("%s/tmp.ccache-trace.%d", tmpdir(), (int)getpid()));
 #endif
-       }
-
-       conf_free(conf);
-       MTR_BEGIN("config", "conf_create");
-       conf = conf_create();
-       MTR_END("config", "conf_create");
-
-       char *errmsg;
-       char *p = getenv("CCACHE_CONFIGPATH");
-       if (p) {
-               primary_config_path = x_strdup(p);
-       } else {
-               secondary_config_path = format("%s/ccache.conf", TO_STRING(SYSCONFDIR));
-               MTR_BEGIN("config", "conf_read_secondary");
-               if (!conf_read(conf, secondary_config_path, &errmsg)) {
-                       if (errno == 0) {
-                               // We could read the file but it contained errors.
-                               fatal("%s", errmsg);
-                       }
-                       // A missing config file in SYSCONFDIR is OK.
-                       free(errmsg);
-               }
-               MTR_END("config", "conf_read_secondary");
-
-               if (str_eq(conf->cache_dir, "")) {
-                       fatal("configuration setting \"cache_dir\" must not be the empty string");
-               }
-               if ((p = getenv("CCACHE_DIR"))) {
-                       free(conf->cache_dir);
-                       conf->cache_dir = strdup(p);
-               }
-               if (str_eq(conf->cache_dir, "")) {
-                       fatal("CCACHE_DIR must not be the empty string");
-               }
-
-               primary_config_path = format("%s/ccache.conf", conf->cache_dir);
-       }
-
-       bool should_create_initial_config = false;
-       MTR_BEGIN("config", "conf_read_primary");
-       if (!conf_read(conf, primary_config_path, &errmsg)) {
-               if (errno == 0) {
-                       // We could read the file but it contained errors.
-                       fatal("%s", errmsg);
-               }
-               if (!conf->disable) {
-                       should_create_initial_config = true;
-               }
-       }
-       MTR_END("config", "conf_read_primary");
-
-       MTR_BEGIN("config", "conf_update_from_environment");
-       if (!conf_update_from_environment(conf, &errmsg)) {
-               fatal("%s", errmsg);
-       }
-       MTR_END("config", "conf_update_from_environment");
-
-       if (should_create_initial_config) {
-               create_initial_config_file(primary_config_path);
-       }
-
-       exitfn_init();
-       exitfn_add_nullary(stats_flush);
-       exitfn_add_nullary(clean_up_pending_tmp_files);
-
-       cc_log("=== CCACHE %s STARTED =========================================",
-              CCACHE_VERSION);
-
-       if (conf->umask != UINT_MAX) {
-               umask(conf->umask);
-       }
-
-       if (enable_internal_trace) {
+  }
+
+  conf_free(conf);
+  MTR_BEGIN("config", "conf_create");
+  conf = conf_create();
+  MTR_END("config", "conf_create");
+
+  char* errmsg;
+  char* p = getenv("CCACHE_CONFIGPATH");
+  if (p) {
+    primary_config_path = x_strdup(p);
+  } else {
+    secondary_config_path = format("%s/ccache.conf", TO_STRING(SYSCONFDIR));
+    MTR_BEGIN("config", "conf_read_secondary");
+    if (!conf_read(conf, secondary_config_path, &errmsg)) {
+      if (errno == 0) {
+        // We could read the file but it contained errors.
+        fatal("%s", errmsg);
+      }
+      // A missing config file in SYSCONFDIR is OK.
+      free(errmsg);
+    }
+    MTR_END("config", "conf_read_secondary");
+
+    if (str_eq(conf->cache_dir, "")) {
+      fatal("configuration setting \"cache_dir\" must not be the empty string");
+    }
+    if ((p = getenv("CCACHE_DIR"))) {
+      free(conf->cache_dir);
+      conf->cache_dir = strdup(p);
+    }
+    if (str_eq(conf->cache_dir, "")) {
+      fatal("CCACHE_DIR must not be the empty string");
+    }
+
+    primary_config_path = format("%s/ccache.conf", conf->cache_dir);
+  }
+
+  bool should_create_initial_config = false;
+  MTR_BEGIN("config", "conf_read_primary");
+  if (!conf_read(conf, primary_config_path, &errmsg)) {
+    if (errno == 0) {
+      // We could read the file but it contained errors.
+      fatal("%s", errmsg);
+    }
+    if (!conf->disable) {
+      should_create_initial_config = true;
+    }
+  }
+  MTR_END("config", "conf_read_primary");
+
+  MTR_BEGIN("config", "conf_update_from_environment");
+  if (!conf_update_from_environment(conf, &errmsg)) {
+    fatal("%s", errmsg);
+  }
+  MTR_END("config", "conf_update_from_environment");
+
+  if (should_create_initial_config) {
+    create_initial_config_file(primary_config_path);
+  }
+
+  exitfn_init();
+  exitfn_add_nullary(stats_flush);
+  exitfn_add_nullary(clean_up_pending_tmp_files);
+
+  cc_log("=== CCACHE %s STARTED =========================================",
+         CCACHE_VERSION);
+
+  if (conf->umask != UINT_MAX) {
+    umask(conf->umask);
+  }
+
+  if (enable_internal_trace) {
 #ifdef MTR_ENABLED
-               trace_start();
-               exitfn_add_nullary(trace_stop);
+    trace_start();
+    exitfn_add_nullary(trace_stop);
 #else
-               cc_log("Error: tracing is not enabled!");
+    cc_log("Error: tracing is not enabled!");
 #endif
-       }
+  }
 }
 
 // Reset the global state. Used by the test suite.
 void
 cc_reset(void)
 {
-       conf_free(conf); conf = NULL;
-       free(primary_config_path); primary_config_path = NULL;
-       free(secondary_config_path); secondary_config_path = NULL;
-       free(current_working_dir); current_working_dir = NULL;
-       for (size_t i = 0; i < debug_prefix_maps_len; i++) {
-               free(debug_prefix_maps[i]);
-               debug_prefix_maps[i] = NULL;
-       }
-       free(debug_prefix_maps); debug_prefix_maps = NULL;
-       debug_prefix_maps_len = 0;
-       free(profile_dir); profile_dir = NULL;
-       for (size_t i = 0; i < sanitize_blacklists_len; i++) {
-               free(sanitize_blacklists[i]);
-               sanitize_blacklists[i] = NULL;
-       }
-       free(sanitize_blacklists); sanitize_blacklists = NULL;
-       sanitize_blacklists_len = 0;
-       free(included_pch_file); included_pch_file = NULL;
-       args_free(orig_args); orig_args = NULL;
-       free(input_file); input_file = NULL;
-       free(output_obj); output_obj = NULL;
-       free(output_dep); output_dep = NULL;
-       free(output_cov); output_cov = NULL;
-       free(output_su); output_su = NULL;
-       free(output_dia); output_dia = NULL;
-       free(output_dwo); output_dwo = NULL;
-       free(cached_result_name); cached_result_name = NULL;
-       free(cached_result_path); cached_result_path = NULL;
-       free(manifest_path); manifest_path = NULL;
-       time_of_compilation = 0;
-       for (size_t i = 0; i < ignore_headers_len; i++) {
-               free(ignore_headers[i]);
-               ignore_headers[i] = NULL;
-       }
-       free(ignore_headers); ignore_headers = NULL;
-       ignore_headers_len = 0;
-       if (included_files) {
-               hashtable_destroy(included_files, 1); included_files = NULL;
-       }
-       has_absolute_include_headers = false;
-       generating_debuginfo = false;
-       generating_debuginfo_level_3 = false;
-       generating_dependencies = false;
-       generating_coverage = false;
-       generating_stackusage = false;
-       profile_arcs = false;
-       free(profile_dir); profile_dir = NULL;
-       i_tmpfile = NULL;
-       direct_i_file = false;
-       free(cpp_stderr); cpp_stderr = NULL;
-       free(stats_file); stats_file = NULL;
-       output_is_precompiled_header = false;
-
-       conf = conf_create();
-       seen_split_dwarf = false;
+  conf_free(conf);
+  conf = NULL;
+  free(primary_config_path);
+  primary_config_path = NULL;
+  free(secondary_config_path);
+  secondary_config_path = NULL;
+  free(current_working_dir);
+  current_working_dir = NULL;
+  for (size_t i = 0; i < debug_prefix_maps_len; i++) {
+    free(debug_prefix_maps[i]);
+    debug_prefix_maps[i] = NULL;
+  }
+  free(debug_prefix_maps);
+  debug_prefix_maps = NULL;
+  debug_prefix_maps_len = 0;
+  free(profile_dir);
+  profile_dir = NULL;
+  for (size_t i = 0; i < sanitize_blacklists_len; i++) {
+    free(sanitize_blacklists[i]);
+    sanitize_blacklists[i] = NULL;
+  }
+  free(sanitize_blacklists);
+  sanitize_blacklists = NULL;
+  sanitize_blacklists_len = 0;
+  free(included_pch_file);
+  included_pch_file = NULL;
+  args_free(orig_args);
+  orig_args = NULL;
+  free(input_file);
+  input_file = NULL;
+  free(output_obj);
+  output_obj = NULL;
+  free(output_dep);
+  output_dep = NULL;
+  free(output_cov);
+  output_cov = NULL;
+  free(output_su);
+  output_su = NULL;
+  free(output_dia);
+  output_dia = NULL;
+  free(output_dwo);
+  output_dwo = NULL;
+  free(cached_result_name);
+  cached_result_name = NULL;
+  free(cached_result_path);
+  cached_result_path = NULL;
+  free(manifest_path);
+  manifest_path = NULL;
+  time_of_compilation = 0;
+  for (size_t i = 0; i < ignore_headers_len; i++) {
+    free(ignore_headers[i]);
+    ignore_headers[i] = NULL;
+  }
+  free(ignore_headers);
+  ignore_headers = NULL;
+  ignore_headers_len = 0;
+  if (included_files) {
+    hashtable_destroy(included_files, 1);
+    included_files = NULL;
+  }
+  has_absolute_include_headers = false;
+  generating_debuginfo = false;
+  generating_debuginfo_level_3 = false;
+  generating_dependencies = false;
+  generating_coverage = false;
+  generating_stackusage = false;
+  profile_arcs = false;
+  free(profile_dir);
+  profile_dir = NULL;
+  i_tmpfile = NULL;
+  direct_i_file = false;
+  free(cpp_stderr);
+  cpp_stderr = NULL;
+  free(stats_file);
+  stats_file = NULL;
+  output_is_precompiled_header = false;
+
+  conf = conf_create();
+  seen_split_dwarf = false;
 }
 
 // Make a copy of stderr that will not be cached, so things like distcc can
@@ -3652,441 +3680,434 @@ cc_reset(void)
 static void
 set_up_uncached_err(void)
 {
-       int uncached_fd = dup(2); // The file descriptor is intentionally leaked.
-       if (uncached_fd == -1) {
-               cc_log("dup(2) failed: %s", strerror(errno));
-               failed();
-       }
-
-       // Leak a pointer to the environment.
-       char *buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
-       if (putenv(buf) == -1) {
-               cc_log("putenv failed: %s", strerror(errno));
-               failed();
-       }
+  int uncached_fd = dup(2); // The file descriptor is intentionally leaked.
+  if (uncached_fd == -1) {
+    cc_log("dup(2) failed: %s", strerror(errno));
+    failed();
+  }
+
+  // Leak a pointer to the environment.
+  char* buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
+  if (putenv(buf) == -1) {
+    cc_log("putenv failed: %s", strerror(errno));
+    failed();
+  }
 }
 
 static void
-configuration_logger(const char *descr, const char *origin, void *context)
+configuration_logger(const char* descr, const char* origin, void* context)
 {
-       (void)context;
-       cc_bulklog("Config: (%s) %s", origin, descr);
+  (void)context;
+  cc_bulklog("Config: (%s) %s", origin, descr);
 }
 
-static void ccache(int argc, char *argv[]) ATTR_NORETURN;
+static void ccache(int argc, charargv[]) ATTR_NORETURN;
 
 // The main ccache driver function.
 static void
-ccache(int argc, char *argv[])
+ccache(int argc, charargv[])
 {
 #ifndef _WIN32
-       set_up_signal_handlers();
+  set_up_signal_handlers();
 #endif
 
-       // Needed for portability when using localtime_r.
-       tzset();
-
-       orig_args = args_init(argc, argv);
-
-       initialize();
-       MTR_BEGIN("main", "find_compiler");
-       find_compiler(argv);
-       MTR_END("main", "find_compiler");
-
-       MTR_BEGIN("main", "clean_up_internal_tempdir");
-       if (str_eq(conf->temporary_dir, "")) {
-               clean_up_internal_tempdir();
-       }
-       MTR_END("main", "clean_up_internal_tempdir");
-
-       if (!str_eq(conf->log_file, "") || conf->debug) {
-               conf_print_items(conf, configuration_logger, NULL);
-       }
-
-       if (conf->disable) {
-               cc_log("ccache is disabled");
-               failed();
-       }
-
-       MTR_BEGIN("main", "set_up_uncached_err");
-       set_up_uncached_err();
-       MTR_END("main", "set_up_uncached_err");
-
-       cc_log_argv("Command line: ", argv);
-       cc_log("Hostname: %s", get_hostname());
-       cc_log("Working directory: %s", get_current_working_dir());
-
-       conf->limit_multiple = MIN(MAX(conf->limit_multiple, 0.0), 1.0);
-
-       MTR_BEGIN("main", "guess_compiler");
-       guessed_compiler = guess_compiler(orig_args->argv[0]);
-       MTR_END("main", "guess_compiler");
-
-       // Arguments (except -E) to send to the preprocessor.
-       struct args *preprocessor_args;
-       // Arguments to send to the real compiler.
-       struct args *compiler_args;
-       MTR_BEGIN("main", "process_args");
-       if (!cc_process_args(orig_args, &preprocessor_args, &compiler_args)) {
-               failed();
-       }
-       MTR_END("main", "process_args");
-
-       if (conf->depend_mode
-           && (!generating_dependencies || str_eq(output_dep, "/dev/null")
-               || !conf->run_second_cpp || conf->unify)) {
-               cc_log("Disabling depend mode");
-               conf->depend_mode = false;
-       }
-
-       cc_log("Source file: %s", input_file);
-       if (generating_dependencies) {
-               cc_log("Dependency file: %s", output_dep);
-       }
-       if (generating_coverage) {
-               cc_log("Coverage file: %s", output_cov);
-       }
-       if (generating_stackusage) {
-               cc_log("Stack usage file: %s", output_su);
-       }
-       if (generating_diagnostics) {
-               cc_log("Diagnostics file: %s", output_dia);
-       }
-       if (output_dwo) {
-               cc_log("Split dwarf file: %s", output_dwo);
-       }
-
-       cc_log("Object file: %s", output_obj);
-       MTR_META_THREAD_NAME(output_obj);
-
-       // Need to dump log buffer as the last exit function to not lose any logs.
-       exitfn_add_last(dump_debug_log_buffer_exitfn, output_obj);
-
-       FILE *debug_text_file = NULL;
-       if (conf->debug) {
-               char *path = format("%s.ccache-input-text", output_obj);
-               debug_text_file = fopen(path, "w");
-               if (debug_text_file) {
-                       exitfn_add(fclose_exitfn, debug_text_file);
-               } else {
-                       cc_log("Failed to open %s: %s", path, strerror(errno));
-               }
-               free(path);
-       }
-
-       struct hash *common_hash = hash_init();
-       init_hash_debug(common_hash, output_obj, 'c', "COMMON", debug_text_file);
-
-       MTR_BEGIN("hash", "common_hash");
-       hash_common_info(preprocessor_args, common_hash);
-       MTR_END("hash", "common_hash");
-
-       // Try to find the hash using the manifest.
-       struct hash *direct_hash = hash_copy(common_hash);
-       init_hash_debug(
-               direct_hash, output_obj, 'd', "DIRECT MODE", debug_text_file);
-
-       bool put_result_in_manifest = false;
-       struct digest *result_name = NULL;
-       struct digest *result_name_from_manifest = NULL;
-       if (conf->direct_mode) {
-               cc_log("Trying direct lookup");
-               MTR_BEGIN("hash", "direct_hash");
-               result_name = calculate_result_name(preprocessor_args, direct_hash, 1);
-               MTR_END("hash", "direct_hash");
-               if (result_name) {
-                       update_cached_result_globals(result_name);
-
-                       // If we can return from cache at this point then do so.
-                       from_cache(FROMCACHE_DIRECT_MODE, 0);
-
-                       // Wasn't able to return from cache at this point. However, the result
-                       // was already found in manifest, so don't re-add it later.
-                       put_result_in_manifest = false;
-
-                       result_name_from_manifest = result_name;
-               } else {
-                       // Add result to manifest later.
-                       put_result_in_manifest = true;
-               }
-       }
-
-       if (conf->read_only_direct) {
-               cc_log("Read-only direct mode; running real compiler");
-               failed();
-       }
-
-       if (!conf->depend_mode) {
-               // Find the hash using the preprocessed output. Also updates
-               // included_files.
-               struct hash *cpp_hash = hash_copy(common_hash);
-               init_hash_debug(
-                       cpp_hash, output_obj, 'p', "PREPROCESSOR MODE", debug_text_file);
-
-               MTR_BEGIN("hash", "cpp_hash");
-               result_name = calculate_result_name(preprocessor_args, cpp_hash, 0);
-               MTR_END("hash", "cpp_hash");
-               if (!result_name) {
-                       fatal("internal error: calculate_result_name returned NULL for cpp");
-               }
-               update_cached_result_globals(result_name);
-
-               if (result_name_from_manifest
-                   && !digests_equal(result_name_from_manifest, result_name)) {
-                       // The hash from manifest differs from the hash of the preprocessor
-                       // output. This could be because:
-                       //
-                       // - The preprocessor produces different output for the same input (not
-                       //   likely).
-                       // - There's a bug in ccache (maybe incorrect handling of compiler
-                       //   arguments).
-                       // - The user has used a different CCACHE_BASEDIR (most likely).
-                       //
-                       // The best thing here would probably be to remove the hash entry from
-                       // the manifest. For now, we use a simpler method: just remove the
-                       // manifest file.
-                       cc_log("Hash from manifest doesn't match preprocessor output");
-                       cc_log("Likely reason: different CCACHE_BASEDIRs used");
-                       cc_log("Removing manifest as a safety measure");
-                       x_unlink(manifest_path);
-
-                       put_result_in_manifest = true;
-               }
-
-               // If we can return from cache at this point then do.
-               from_cache(FROMCACHE_CPP_MODE, put_result_in_manifest);
-       }
-
-       if (conf->read_only) {
-               cc_log("Read-only mode; running real compiler");
-               failed();
-       }
-
-       add_prefix(compiler_args, conf->prefix_command);
-
-       // In depend_mode, extend the direct hash.
-       struct hash *depend_mode_hash = conf->depend_mode ? direct_hash : NULL;
-
-       // Run real compiler, sending output to cache.
-       MTR_BEGIN("cache", "to_cache");
-       to_cache(compiler_args, depend_mode_hash);
-       MTR_END("cache", "to_cache");
-
-       x_exit(0);
+  // Needed for portability when using localtime_r.
+  tzset();
+
+  orig_args = args_init(argc, argv);
+
+  initialize();
+  MTR_BEGIN("main", "find_compiler");
+  find_compiler(argv);
+  MTR_END("main", "find_compiler");
+
+  MTR_BEGIN("main", "clean_up_internal_tempdir");
+  if (str_eq(conf->temporary_dir, "")) {
+    clean_up_internal_tempdir();
+  }
+  MTR_END("main", "clean_up_internal_tempdir");
+
+  if (!str_eq(conf->log_file, "") || conf->debug) {
+    conf_print_items(conf, configuration_logger, NULL);
+  }
+
+  if (conf->disable) {
+    cc_log("ccache is disabled");
+    failed();
+  }
+
+  MTR_BEGIN("main", "set_up_uncached_err");
+  set_up_uncached_err();
+  MTR_END("main", "set_up_uncached_err");
+
+  cc_log_argv("Command line: ", argv);
+  cc_log("Hostname: %s", get_hostname());
+  cc_log("Working directory: %s", get_current_working_dir());
+
+  conf->limit_multiple = MIN(MAX(conf->limit_multiple, 0.0), 1.0);
+
+  MTR_BEGIN("main", "guess_compiler");
+  guessed_compiler = guess_compiler(orig_args->argv[0]);
+  MTR_END("main", "guess_compiler");
+
+  // Arguments (except -E) to send to the preprocessor.
+  struct args* preprocessor_args;
+  // Arguments to send to the real compiler.
+  struct args* compiler_args;
+  MTR_BEGIN("main", "process_args");
+  if (!cc_process_args(orig_args, &preprocessor_args, &compiler_args)) {
+    failed();
+  }
+  MTR_END("main", "process_args");
+
+  if (conf->depend_mode
+      && (!generating_dependencies || str_eq(output_dep, "/dev/null")
+          || !conf->run_second_cpp || conf->unify)) {
+    cc_log("Disabling depend mode");
+    conf->depend_mode = false;
+  }
+
+  cc_log("Source file: %s", input_file);
+  if (generating_dependencies) {
+    cc_log("Dependency file: %s", output_dep);
+  }
+  if (generating_coverage) {
+    cc_log("Coverage file: %s", output_cov);
+  }
+  if (generating_stackusage) {
+    cc_log("Stack usage file: %s", output_su);
+  }
+  if (generating_diagnostics) {
+    cc_log("Diagnostics file: %s", output_dia);
+  }
+  if (output_dwo) {
+    cc_log("Split dwarf file: %s", output_dwo);
+  }
+
+  cc_log("Object file: %s", output_obj);
+  MTR_META_THREAD_NAME(output_obj);
+
+  // Need to dump log buffer as the last exit function to not lose any logs.
+  exitfn_add_last(dump_debug_log_buffer_exitfn, output_obj);
+
+  FILE* debug_text_file = NULL;
+  if (conf->debug) {
+    char* path = format("%s.ccache-input-text", output_obj);
+    debug_text_file = fopen(path, "w");
+    if (debug_text_file) {
+      exitfn_add(fclose_exitfn, debug_text_file);
+    } else {
+      cc_log("Failed to open %s: %s", path, strerror(errno));
+    }
+    free(path);
+  }
+
+  struct hash* common_hash = hash_init();
+  init_hash_debug(common_hash, output_obj, 'c', "COMMON", debug_text_file);
+
+  MTR_BEGIN("hash", "common_hash");
+  hash_common_info(preprocessor_args, common_hash);
+  MTR_END("hash", "common_hash");
+
+  // Try to find the hash using the manifest.
+  struct hash* direct_hash = hash_copy(common_hash);
+  init_hash_debug(direct_hash, output_obj, 'd', "DIRECT MODE", debug_text_file);
+
+  bool put_result_in_manifest = false;
+  struct digest* result_name = NULL;
+  struct digest* result_name_from_manifest = NULL;
+  if (conf->direct_mode) {
+    cc_log("Trying direct lookup");
+    MTR_BEGIN("hash", "direct_hash");
+    result_name = calculate_result_name(preprocessor_args, direct_hash, 1);
+    MTR_END("hash", "direct_hash");
+    if (result_name) {
+      update_cached_result_globals(result_name);
+
+      // If we can return from cache at this point then do so.
+      from_cache(FROMCACHE_DIRECT_MODE, 0);
+
+      // Wasn't able to return from cache at this point. However, the result
+      // was already found in manifest, so don't re-add it later.
+      put_result_in_manifest = false;
+
+      result_name_from_manifest = result_name;
+    } else {
+      // Add result to manifest later.
+      put_result_in_manifest = true;
+    }
+  }
+
+  if (conf->read_only_direct) {
+    cc_log("Read-only direct mode; running real compiler");
+    failed();
+  }
+
+  if (!conf->depend_mode) {
+    // Find the hash using the preprocessed output. Also updates
+    // included_files.
+    struct hash* cpp_hash = hash_copy(common_hash);
+    init_hash_debug(
+      cpp_hash, output_obj, 'p', "PREPROCESSOR MODE", debug_text_file);
+
+    MTR_BEGIN("hash", "cpp_hash");
+    result_name = calculate_result_name(preprocessor_args, cpp_hash, 0);
+    MTR_END("hash", "cpp_hash");
+    if (!result_name) {
+      fatal("internal error: calculate_result_name returned NULL for cpp");
+    }
+    update_cached_result_globals(result_name);
+
+    if (result_name_from_manifest
+        && !digests_equal(result_name_from_manifest, result_name)) {
+      // The hash from manifest differs from the hash of the preprocessor
+      // output. This could be because:
+      //
+      // - The preprocessor produces different output for the same input (not
+      //   likely).
+      // - There's a bug in ccache (maybe incorrect handling of compiler
+      //   arguments).
+      // - The user has used a different CCACHE_BASEDIR (most likely).
+      //
+      // The best thing here would probably be to remove the hash entry from
+      // the manifest. For now, we use a simpler method: just remove the
+      // manifest file.
+      cc_log("Hash from manifest doesn't match preprocessor output");
+      cc_log("Likely reason: different CCACHE_BASEDIRs used");
+      cc_log("Removing manifest as a safety measure");
+      x_unlink(manifest_path);
+
+      put_result_in_manifest = true;
+    }
+
+    // If we can return from cache at this point then do.
+    from_cache(FROMCACHE_CPP_MODE, put_result_in_manifest);
+  }
+
+  if (conf->read_only) {
+    cc_log("Read-only mode; running real compiler");
+    failed();
+  }
+
+  add_prefix(compiler_args, conf->prefix_command);
+
+  // In depend_mode, extend the direct hash.
+  struct hash* depend_mode_hash = conf->depend_mode ? direct_hash : NULL;
+
+  // Run real compiler, sending output to cache.
+  MTR_BEGIN("cache", "to_cache");
+  to_cache(compiler_args, depend_mode_hash);
+  MTR_END("cache", "to_cache");
+
+  x_exit(0);
 }
 
 static void
-configuration_printer(const char *descr, const char *origin, void *context)
+configuration_printer(const char* descr, const char* origin, void* context)
 {
-       assert(context);
-       auto f = static_cast<FILE*>(context);
-       fprintf(f, "(%s) %s\n", origin, descr);
+  assert(context);
+  auto f = static_cast<FILE*>(context);
+  fprintf(f, "(%s) %s\n", origin, descr);
 }
 
 // The main program when not doing a compile.
 static int
-ccache_main_options(int argc, char *argv[])
+ccache_main_options(int argc, charargv[])
 {
-       enum longopts {
-               DUMP_MANIFEST,
-               DUMP_RESULT,
-               HASH_FILE,
-               PRINT_STATS,
-       };
-       static const struct option options[] = {
-               {"cleanup",             no_argument,       0, 'c'},
-               {"clear",               no_argument,       0, 'C'},
-               {"dump-manifest",       required_argument, 0, DUMP_MANIFEST},
-               {"dump-result",         required_argument, 0, DUMP_RESULT},
-               {"get-config",          required_argument, 0, 'k'},
-               {"hash-file",           required_argument, 0, HASH_FILE},
-               {"help",                no_argument,       0, 'h'},
-               {"max-files",           required_argument, 0, 'F'},
-               {"max-size",            required_argument, 0, 'M'},
-               {"print-stats",         no_argument,       0, PRINT_STATS},
-               {"set-config",          required_argument, 0, 'o'},
-               {"show-compression",    no_argument,       0, 'x'},
-               {"show-config",         no_argument,       0, 'p'},
-               {"show-stats",          no_argument,       0, 's'},
-               {"version",             no_argument,       0, 'V'},
-               {"zero-stats",          no_argument,       0, 'z'},
-               {0, 0, 0, 0}
-       };
-
-       int c;
-       while ((c = getopt_long(argc, argv, "cCk:hF:M:po:sVxz", options, NULL))
-              != -1) {
-               switch (c) {
-               case DUMP_MANIFEST:
-                       initialize();
-                       manifest_dump(optarg, stdout);
-                       break;
-
-               case DUMP_RESULT:
-                       initialize();
-                       if (!result_dump(optarg, stdout)) {
-                               return 1;
-                       }
-                       break;
-
-               case HASH_FILE:
-               {
-                       initialize();
-                       struct hash *hash = hash_init();
-                       if (str_eq(optarg, "-")) {
-                               hash_fd(hash, STDIN_FILENO);
-                       } else {
-                               hash_file(hash, optarg);
-                       }
-                       char digest[DIGEST_STRING_BUFFER_SIZE];
-                       hash_result_as_string(hash, digest);
-                       puts(digest);
-                       hash_free(hash);
-                       break;
-               }
-
-               case PRINT_STATS:
-                       initialize();
-                       stats_print();
-                       break;
-
-               case 'c': // --cleanup
-                       initialize();
-                       clean_up_all(conf);
-                       printf("Cleaned cache\n");
-                       break;
-
-               case 'C': // --clear
-                       initialize();
-                       wipe_all(conf);
-                       printf("Cleared cache\n");
-                       break;
-
-               case 'h': // --help
-                       fputs(USAGE_TEXT, stdout);
-                       x_exit(0);
-
-               case 'k': // --get-config
-               {
-                       initialize();
-                       char *errmsg;
-                       if (!conf_print_value(conf, optarg, stdout, &errmsg)) {
-                               fatal("%s", errmsg);
-                       }
-               }
-               break;
-
-               case 'F': // --max-files
-               {
-                       initialize();
-                       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 {
-                                       printf("Set cache file limit to %u\n", files);
-                               }
-                       } else {
-                               fatal("could not set cache file limit: %s", errmsg);
-                       }
-               }
-               break;
-
-               case 'M': // --max-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) {
-                                       printf("Unset cache size limit\n");
-                               } else {
-                                       char *s = format_human_readable_size(size);
-                                       printf("Set cache size limit to %s\n", s);
-                                       free(s);
-                               }
-                       } else {
-                               fatal("could not set cache size limit: %s", errmsg);
-                       }
-               }
-               break;
-
-               case 'o': // --set-config
-               {
-                       initialize();
-                       char *p = strchr(optarg, '=');
-                       if (!p) {
-                               fatal("missing equal sign in \"%s\"", optarg);
-                       }
-                       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);
-                       }
-                       free(key);
-               }
-               break;
-
-               case 'p': // --show-config
-                       initialize();
-                       conf_print_items(conf, configuration_printer, stdout);
-                       break;
-
-               case 's': // --show-stats
-                       initialize();
-                       stats_summary();
-                       break;
-
-               case 'V': // --version
-                       fprintf(stdout, VERSION_TEXT, CCACHE_VERSION);
-                       x_exit(0);
-
-               case 'x': // --show-compression
-                       initialize();
-                       compress_stats(conf);
-                       break;
-
-               case 'z': // --zero-stats
-                       initialize();
-                       stats_zero();
-                       printf("Statistics zeroed\n");
-                       break;
-
-               default:
-                       fputs(USAGE_TEXT, stderr);
-                       x_exit(1);
-               }
-       }
-
-       return 0;
+  enum longopts {
+    DUMP_MANIFEST,
+    DUMP_RESULT,
+    HASH_FILE,
+    PRINT_STATS,
+  };
+  static const struct option options[] = {
+    {"cleanup", no_argument, 0, 'c'},
+    {"clear", no_argument, 0, 'C'},
+    {"dump-manifest", required_argument, 0, DUMP_MANIFEST},
+    {"dump-result", required_argument, 0, DUMP_RESULT},
+    {"get-config", required_argument, 0, 'k'},
+    {"hash-file", required_argument, 0, HASH_FILE},
+    {"help", no_argument, 0, 'h'},
+    {"max-files", required_argument, 0, 'F'},
+    {"max-size", required_argument, 0, 'M'},
+    {"print-stats", no_argument, 0, PRINT_STATS},
+    {"set-config", required_argument, 0, 'o'},
+    {"show-compression", no_argument, 0, 'x'},
+    {"show-config", no_argument, 0, 'p'},
+    {"show-stats", no_argument, 0, 's'},
+    {"version", no_argument, 0, 'V'},
+    {"zero-stats", no_argument, 0, 'z'},
+    {0, 0, 0, 0}};
+
+  int c;
+  while ((c = getopt_long(argc, argv, "cCk:hF:M:po:sVxz", options, NULL))
+         != -1) {
+    switch (c) {
+    case DUMP_MANIFEST:
+      initialize();
+      manifest_dump(optarg, stdout);
+      break;
+
+    case DUMP_RESULT:
+      initialize();
+      if (!result_dump(optarg, stdout)) {
+        return 1;
+      }
+      break;
+
+    case HASH_FILE: {
+      initialize();
+      struct hash* hash = hash_init();
+      if (str_eq(optarg, "-")) {
+        hash_fd(hash, STDIN_FILENO);
+      } else {
+        hash_file(hash, optarg);
+      }
+      char digest[DIGEST_STRING_BUFFER_SIZE];
+      hash_result_as_string(hash, digest);
+      puts(digest);
+      hash_free(hash);
+      break;
+    }
+
+    case PRINT_STATS:
+      initialize();
+      stats_print();
+      break;
+
+    case 'c': // --cleanup
+      initialize();
+      clean_up_all(conf);
+      printf("Cleaned cache\n");
+      break;
+
+    case 'C': // --clear
+      initialize();
+      wipe_all(conf);
+      printf("Cleared cache\n");
+      break;
+
+    case 'h': // --help
+      fputs(USAGE_TEXT, stdout);
+      x_exit(0);
+
+    case 'k': // --get-config
+    {
+      initialize();
+      char* errmsg;
+      if (!conf_print_value(conf, optarg, stdout, &errmsg)) {
+        fatal("%s", errmsg);
+      }
+    } break;
+
+    case 'F': // --max-files
+    {
+      initialize();
+      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 {
+          printf("Set cache file limit to %u\n", files);
+        }
+      } else {
+        fatal("could not set cache file limit: %s", errmsg);
+      }
+    } break;
+
+    case 'M': // --max-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) {
+          printf("Unset cache size limit\n");
+        } else {
+          char* s = format_human_readable_size(size);
+          printf("Set cache size limit to %s\n", s);
+          free(s);
+        }
+      } else {
+        fatal("could not set cache size limit: %s", errmsg);
+      }
+    } break;
+
+    case 'o': // --set-config
+    {
+      initialize();
+      char* p = strchr(optarg, '=');
+      if (!p) {
+        fatal("missing equal sign in \"%s\"", optarg);
+      }
+      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);
+      }
+      free(key);
+    } break;
+
+    case 'p': // --show-config
+      initialize();
+      conf_print_items(conf, configuration_printer, stdout);
+      break;
+
+    case 's': // --show-stats
+      initialize();
+      stats_summary();
+      break;
+
+    case 'V': // --version
+      fprintf(stdout, VERSION_TEXT, CCACHE_VERSION);
+      x_exit(0);
+
+    case 'x': // --show-compression
+      initialize();
+      compress_stats(conf);
+      break;
+
+    case 'z': // --zero-stats
+      initialize();
+      stats_zero();
+      printf("Statistics zeroed\n");
+      break;
+
+    default:
+      fputs(USAGE_TEXT, stderr);
+      x_exit(1);
+    }
+  }
+
+  return 0;
 }
 
-int ccache_main(int argc, char *argv[]);
+int ccache_main(int argc, charargv[]);
 
 int
-ccache_main(int argc, char *argv[])
+ccache_main(int argc, charargv[])
 {
-       // Check if we are being invoked as "ccache".
-       char *program_name = x_basename(argv[0]);
-       if (same_executable_name(program_name, MYNAME)) {
-               if (argc < 2) {
-                       fputs(USAGE_TEXT, stderr);
-                       x_exit(1);
-               }
-               // If the first argument isn't an option, then assume we are being passed a
-               // compiler name and options.
-               if (argv[1][0] == '-') {
-                       return ccache_main_options(argc, argv);
-               }
-       }
-       free(program_name);
-
-       ccache(argc, argv);
+  // Check if we are being invoked as "ccache".
+  char* program_name = x_basename(argv[0]);
+  if (same_executable_name(program_name, MYNAME)) {
+    if (argc < 2) {
+      fputs(USAGE_TEXT, stderr);
+      x_exit(1);
+    }
+    // If the first argument isn't an option, then assume we are being passed a
+    // compiler name and options.
+    if (argv[1][0] == '-') {
+      return ccache_main_options(argc, argv);
+    }
+  }
+  free(program_name);
+
+  ccache(argc, argv);
 }
index 089f6b754331e01004def2319f28432ceae5354a..e8be9244dbab3fadf160b0cf2cc6d8f0168b8b30 100644 (file)
 #pragma once
 
 #include "system.hpp"
+
 #include "conf.hpp"
 #include "counters.hpp"
+
 #include "third_party/minitrace.h"
 
 #ifdef __GNUC__
-#define ATTR_FORMAT(x, y, z) __attribute__((format (ATTRIBUTE_FORMAT_PRINTF, y, z)))
-#define ATTR_NORETURN __attribute__((noreturn))
+#  define ATTR_FORMAT(x, y, z)                                                 \
+    __attribute__((format(ATTRIBUTE_FORMAT_PRINTF, y, z)))
+#  define ATTR_NORETURN __attribute__((noreturn))
 #else
-#define ATTR_FORMAT(x, y, z)
-#define ATTR_NORETURN
+#  define ATTR_FORMAT(x, y, z)
+#  define ATTR_NORETURN
 #endif
 
 #ifndef MYNAME
-#define MYNAME "ccache"
+#  define MYNAME "ccache"
 #endif
 
 extern const char CCACHE_VERSION[];
 
 // Statistics fields in storage order.
 enum stats {
-       STATS_NONE = 0,
-       STATS_STDOUT = 1,
-       STATS_STATUS = 2,
-       STATS_ERROR = 3,
-       STATS_TOCACHE = 4,
-       STATS_PREPROCESSOR = 5,
-       STATS_COMPILER = 6,
-       STATS_MISSING = 7,
-       STATS_CACHEHIT_CPP = 8,
-       STATS_ARGS = 9,
-       STATS_LINK = 10,
-       STATS_NUMFILES = 11,
-       STATS_TOTALSIZE = 12,
-       STATS_OBSOLETE_MAXFILES = 13,
-       STATS_OBSOLETE_MAXSIZE = 14,
-       STATS_SOURCELANG = 15,
-       STATS_BADOUTPUTFILE = 16,
-       STATS_NOINPUT = 17,
-       STATS_MULTIPLE = 18,
-       STATS_CONFTEST = 19,
-       STATS_UNSUPPORTED_OPTION = 20,
-       STATS_OUTSTDOUT = 21,
-       STATS_CACHEHIT_DIR = 22,
-       STATS_NOOUTPUT = 23,
-       STATS_EMPTYOUTPUT = 24,
-       STATS_BADEXTRAFILE = 25,
-       STATS_COMPCHECK = 26,
-       STATS_CANTUSEPCH = 27,
-       STATS_PREPROCESSING = 28,
-       STATS_NUMCLEANUPS = 29,
-       STATS_UNSUPPORTED_DIRECTIVE = 30,
-       STATS_ZEROTIMESTAMP = 31,
-
-       STATS_END
+  STATS_NONE = 0,
+  STATS_STDOUT = 1,
+  STATS_STATUS = 2,
+  STATS_ERROR = 3,
+  STATS_TOCACHE = 4,
+  STATS_PREPROCESSOR = 5,
+  STATS_COMPILER = 6,
+  STATS_MISSING = 7,
+  STATS_CACHEHIT_CPP = 8,
+  STATS_ARGS = 9,
+  STATS_LINK = 10,
+  STATS_NUMFILES = 11,
+  STATS_TOTALSIZE = 12,
+  STATS_OBSOLETE_MAXFILES = 13,
+  STATS_OBSOLETE_MAXSIZE = 14,
+  STATS_SOURCELANG = 15,
+  STATS_BADOUTPUTFILE = 16,
+  STATS_NOINPUT = 17,
+  STATS_MULTIPLE = 18,
+  STATS_CONFTEST = 19,
+  STATS_UNSUPPORTED_OPTION = 20,
+  STATS_OUTSTDOUT = 21,
+  STATS_CACHEHIT_DIR = 22,
+  STATS_NOOUTPUT = 23,
+  STATS_EMPTYOUTPUT = 24,
+  STATS_BADEXTRAFILE = 25,
+  STATS_COMPCHECK = 26,
+  STATS_CANTUSEPCH = 27,
+  STATS_PREPROCESSING = 28,
+  STATS_NUMCLEANUPS = 29,
+  STATS_UNSUPPORTED_DIRECTIVE = 30,
+  STATS_ZEROTIMESTAMP = 31,
+
+  STATS_END
 };
 
 enum guessed_compiler {
-       GUESSED_CLANG,
-       GUESSED_GCC,
-       GUESSED_NVCC,
-       GUESSED_PUMP,
-       GUESSED_UNKNOWN
+  GUESSED_CLANG,
+  GUESSED_GCC,
+  GUESSED_NVCC,
+  GUESSED_PUMP,
+  GUESSED_UNKNOWN
 };
 
 extern enum guessed_compiler guessed_compiler;
@@ -106,11 +109,11 @@ extern enum guessed_compiler guessed_compiler;
 #define SLOPPY_LOCALE (1U << 9)
 
 #define str_eq(s1, s2) (strcmp((s1), (s2)) == 0)
-#define str_startswith(s, prefix) \
-       (strncmp((s), (prefix), strlen((prefix))) == 0)
-#define str_endswith(s, suffix) \
-       (strlen(s) >= strlen(suffix) \
-        && str_eq((s) + strlen(s) - strlen(suffix), (suffix)))
+#define str_startswith(s, prefix)                                              \
+  (strncmp((s), (prefix), strlen((prefix))) == 0)
+#define str_endswith(s, suffix)                                                \
+  (strlen(s) >= strlen(suffix)                                                 \
+   && str_eq((s) + strlen(s) - strlen(suffix), (suffix)))
 #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
 
 // Buffer size for I/O operations. Should be a multiple of 4 KiB.
@@ -119,99 +122,100 @@ extern enum guessed_compiler guessed_compiler;
 // ----------------------------------------------------------------------------
 // args.c
 
-struct args {
-       char **argv;
-       int argc;
+struct args
+{
+  char** argv;
+  int argc;
 };
 
-struct args *args_init(int, const char * const*);
-struct args *args_init_from_string(const char *);
-struct args *args_init_from_gcc_atfile(const char *filename);
-struct args *args_copy(struct args *args);
-void args_free(struct args *args);
-void args_add(struct args *args, const char *s);
-void args_add_prefix(struct args *args, const char *s);
-void args_extend(struct args *args, struct args *to_append);
-void args_insert(struct args *dest, int index, struct args *src, bool replace);
-void args_pop(struct args *args, int n);
-void args_set(struct args *args, int index, const char *value);
-void args_strip(struct args *args, const char *prefix);
-void args_remove_first(struct args *args);
-char *args_to_string(const struct args *args);
-bool args_equal(const struct args *args1, const struct args *args2);
+struct args* args_init(int, const char* const*);
+struct args* args_init_from_string(const char*);
+struct args* args_init_from_gcc_atfile(const char* filename);
+struct args* args_copy(struct args* args);
+void args_free(struct argsargs);
+void args_add(struct args* args, const char* s);
+void args_add_prefix(struct args* args, const char* s);
+void args_extend(struct args* args, struct args* to_append);
+void args_insert(struct args* dest, int index, struct args* src, bool replace);
+void args_pop(struct argsargs, int n);
+void args_set(struct args* args, int index, const char* value);
+void args_strip(struct args* args, const char* prefix);
+void args_remove_first(struct argsargs);
+char* args_to_string(const struct args* args);
+bool args_equal(const struct args* args1, const struct args* args2);
 
 // ----------------------------------------------------------------------------
 // util.c
 
-void cc_log(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
-void cc_bulklog(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
-void cc_log_argv(const char *prefix, char **argv);
-void cc_dump_debug_log_buffer(const char *path);
-void fatal(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
-void warn(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
+void cc_log(const charformat, ...) ATTR_FORMAT(printf, 1, 2);
+void cc_bulklog(const charformat, ...) ATTR_FORMAT(printf, 1, 2);
+void cc_log_argv(const char* prefix, char** argv);
+void cc_dump_debug_log_buffer(const charpath);
+void fatal(const charformat, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
+void warn(const charformat, ...) ATTR_FORMAT(printf, 1, 2);
 
-char *get_path_in_cache(const char *name, const char *suffix);
+char* get_path_in_cache(const char* name, const char* suffix);
 bool copy_fd(int fd_in, int fd_out);
-bool clone_file(const char *src, const char *dest, bool via_tmp_file);
-bool copy_file(const char *src, const char *dest, bool via_tmp_file);
-bool move_file(const char *src, const char *dest);
-int create_dir(const char *dir);
-int create_parent_dirs(const char *path);
-const char *get_hostname(void);
-const char *tmp_string(void);
-int create_cachedirtag(const char *dir);
-char *format(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
-void format_hex(const uint8_t *data, size_t size, char *buffer);
-void reformat(char **ptr, const char *format, ...) ATTR_FORMAT(printf, 2, 3);
-char *x_strdup(const char *s);
-char *x_strndup(const char *s, size_t n);
-void *x_malloc(size_t size);
-void *x_calloc(size_t nmemb, size_t size);
-void *x_realloc(void *ptr, size_t size);
-void x_setenv(const char *name, const char *value);
-void x_unsetenv(const char *name);
-int x_fstat(int fd, struct stat *buf);
-int x_lstat(const char *pathname, struct stat *buf);
-int x_stat(const char *pathname, struct stat *buf);
-void traverse(const char *dir, void (*fn)(const char *, struct stat *));
-char *x_basename(const char *path);
-char *x_dirname(const char *path);
-const char *get_extension(const char *path);
-char *remove_extension(const char *path);
-size_t file_size(struct stat *st);
-char *format_human_readable_size(uint64_t size);
-char *format_parsable_size_with_suffix(uint64_t size);
-bool parse_size_with_suffix(const char *str, uint64_t *size);
-char *x_realpath(const char *path);
-char *gnu_getcwd(void);
+bool clone_file(const char* src, const char* dest, bool via_tmp_file);
+bool copy_file(const char* src, const char* dest, bool via_tmp_file);
+bool move_file(const char* src, const char* dest);
+int create_dir(const chardir);
+int create_parent_dirs(const charpath);
+const charget_hostname(void);
+const chartmp_string(void);
+int create_cachedirtag(const chardir);
+char* format(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
+void format_hex(const uint8_t* data, size_t size, char* buffer);
+void reformat(char** ptr, const char* format, ...) ATTR_FORMAT(printf, 2, 3);
+char* x_strdup(const char* s);
+char* x_strndup(const char* s, size_t n);
+voidx_malloc(size_t size);
+voidx_calloc(size_t nmemb, size_t size);
+void* x_realloc(void* ptr, size_t size);
+void x_setenv(const char* name, const char* value);
+void x_unsetenv(const charname);
+int x_fstat(int fd, struct statbuf);
+int x_lstat(const char* pathname, struct stat* buf);
+int x_stat(const char* pathname, struct stat* buf);
+void traverse(const char* dir, void (*fn)(const char*, struct stat*));
+char* x_basename(const char* path);
+char* x_dirname(const char* path);
+const char* get_extension(const char* path);
+char* remove_extension(const char* path);
+size_t file_size(struct statst);
+charformat_human_readable_size(uint64_t size);
+charformat_parsable_size_with_suffix(uint64_t size);
+bool parse_size_with_suffix(const char* str, uint64_t* size);
+char* x_realpath(const char* path);
+chargnu_getcwd(void);
 #ifndef HAVE_LOCALTIME_R
-struct tm *localtime_r(const time_t *timep, struct tm *result);
+struct tm* localtime_r(const time_t* timep, struct tm* result);
 #endif
 #ifndef HAVE_STRTOK_R
-char *strtok_r(char *str, const char *delim, char **saveptr);
+char* strtok_r(char* str, const char* delim, char** saveptr);
 #endif
-int create_tmp_fd(char **fname);
-FILE *create_tmp_file(char **fname, const char *mode);
-const char *get_home_directory(void);
-char *get_cwd(void);
-bool same_executable_name(const char *s1, const char *s2);
-size_t common_dir_prefix_length(const char *s1, const char *s2);
-char *get_relative_path(const char *from, const char *to);
-bool is_absolute_path(const char *path);
-bool is_full_path(const char *path);
-bool is_symlink(const char *path);
-void update_mtime(const char *path);
+int create_tmp_fd(char** fname);
+FILE* create_tmp_file(char** fname, const char* mode);
+const charget_home_directory(void);
+charget_cwd(void);
+bool same_executable_name(const char* s1, const char* s2);
+size_t common_dir_prefix_length(const char* s1, const char* s2);
+char* get_relative_path(const char* from, const char* to);
+bool is_absolute_path(const charpath);
+bool is_full_path(const charpath);
+bool is_symlink(const charpath);
+void update_mtime(const charpath);
 void x_exit(int status) ATTR_NORETURN;
-int x_rename(const char *oldpath, const char *newpath);
-int tmp_unlink(const char *path);
-int x_unlink(const char *path);
-int x_try_unlink(const char *path);
+int x_rename(const char* oldpath, const char* newpath);
+int tmp_unlink(const charpath);
+int x_unlink(const charpath);
+int x_try_unlink(const charpath);
 #ifndef _WIN32
-char *x_readlink(const char *path);
+char* x_readlink(const char* path);
 #endif
-bool read_file(const char *path, size_t size_hint, char **data, size_t *size);
-char *read_text_file(const char *path, size_t size_hint);
-char *subst_env_in_string(const char *str, char **errmsg);
+bool read_file(const char* path, size_t size_hint, char** data, size_t* size);
+char* read_text_file(const char* path, size_t size_hint);
+char* subst_env_in_string(const char* str, char** errmsg);
 void set_cloexec_flag(int fd);
 double time_seconds(void);
 
@@ -224,49 +228,50 @@ unsigned stats_get_pending(enum stats stat);
 void stats_zero(void);
 void stats_summary(void);
 void stats_print(void);
-void stats_update_size(const char *sfile, int64_t size, int files);
-void stats_get_obsolete_limits(const char *dir, unsigned *maxfiles,
-                               uint64_t *maxsize);
-void stats_set_sizes(const char *dir, unsigned num_files, uint64_t total_size);
-void stats_add_cleanup(const char *dir, unsigned count);
-void stats_timestamp(time_t time, struct counters *counters);
-void stats_read(const char *path, struct counters *counters);
-void stats_write(const char *path, struct counters *counters);
+void stats_update_size(const char* sfile, int64_t size, int files);
+void stats_get_obsolete_limits(const char* dir,
+                               unsigned* maxfiles,
+                               uint64_t* maxsize);
+void stats_set_sizes(const char* dir, unsigned num_files, uint64_t total_size);
+void stats_add_cleanup(const char* dir, unsigned count);
+void stats_timestamp(time_t time, struct counters* counters);
+void stats_read(const char* path, struct counters* counters);
+void stats_write(const char* path, struct counters* counters);
 
 // ----------------------------------------------------------------------------
 // exitfn.c
 
 void exitfn_init(void);
 void exitfn_add_nullary(void (*function)(void));
-void exitfn_add(void (*function)(void *), void *context);
-void exitfn_add_last(void (*function)(void *), void *context);
+void exitfn_add(void (*function)(void*), void* context);
+void exitfn_add_last(void (*function)(void*), void* context);
 void exitfn_call(void);
 
 // ----------------------------------------------------------------------------
 // cleanup.c
 
-void clean_up_dir(struct conf *conf, const char *dir, double limit_multiple);
-void clean_up_all(struct conf *conf);
-void wipe_all(struct conf *conf);
+void clean_up_dir(struct conf* conf, const char* dir, double limit_multiple);
+void clean_up_all(struct confconf);
+void wipe_all(struct confconf);
 
 // ----------------------------------------------------------------------------
 // compress.c
 
-void compress_stats(struct conf *conf);
+void compress_stats(struct confconf);
 
 // ----------------------------------------------------------------------------
 // execute.c
 
-int execute(char **argv, int fd_out, int fd_err, pid_t *pid);
-char *find_executable(const char *name, const char *exclude_name);
-void print_command(FILE *fp, char **argv);
-char *format_command(const char* const* argv);
+int execute(char** argv, int fd_out, int fd_err, pid_t* pid);
+char* find_executable(const char* name, const char* exclude_name);
+void print_command(FILE* fp, char** argv);
+charformat_command(const char* const* argv);
 
 // ----------------------------------------------------------------------------
 // lockfile.c
 
-bool lockfile_acquire(const char *path, unsigned staleness_limit);
-void lockfile_release(const char *path);
+bool lockfile_acquire(const charpath, unsigned staleness_limit);
+void lockfile_release(const charpath);
 
 // ----------------------------------------------------------------------------
 // ccache.c
@@ -275,52 +280,55 @@ extern time_t time_of_compilation;
 extern bool output_is_precompiled_header;
 void block_signals(void);
 void unblock_signals(void);
-bool cc_process_args(struct args *args, struct args **preprocessor_args,
-                    struct args **compiler_args);
+bool cc_process_args(struct args* args,
+                     struct args** preprocessor_args,
+                     struct args** compiler_args);
 void cc_reset(void);
-bool is_precompiled_header(const char *path);
+bool is_precompiled_header(const charpath);
 
 // ----------------------------------------------------------------------------
 
 #ifdef HAVE_COMPAR_FN_T
-#define COMPAR_FN_T __compar_fn_t
+#  define COMPAR_FN_T __compar_fn_t
 #else
-typedef int (*COMPAR_FN_T)(const void *, const void *);
+typedef int (*COMPAR_FN_T)(const void*, const void*);
 #endif
 
 // Work with silly DOS binary open.
 #ifndef O_BINARY
-#define O_BINARY 0
+#  define O_BINARY 0
 #endif
 
 #ifdef _WIN32
-char *win32argvtos(char *prefix, char **argv, int *length);
-char *win32getshell(char *path);
-int win32execute(char *path, char **argv, int doreturn,
-                 int fd_stdout, int fd_stderr);
-void add_exe_ext_if_no_to_fullpath(char *full_path_win_ext, size_t max_size,
-                                   const char *ext, const char *path);
-#    ifndef _WIN32_WINNT
+char* win32argvtos(char* prefix, char** argv, int* length);
+char* win32getshell(char* path);
+int win32execute(
+  char* path, char** argv, int doreturn, int fd_stdout, int fd_stderr);
+void add_exe_ext_if_no_to_fullpath(char* full_path_win_ext,
+                                   size_t max_size,
+                                   const char* ext,
+                                   const char* path);
+#  ifndef _WIN32_WINNT
 #    define _WIN32_WINNT 0x0501
-#    endif
-#    include <windows.h>
-#    define mkdir(a,b) mkdir(a)
-#    define link(src,dst) (CreateHardLink(dst,src,NULL) ? 0 : -1)
-#    define lstat(a,b) stat(a,b)
-#    define execv(a,b) win32execute(a,b,0,-1,-1)
-#    define execute(a,b,c,d) win32execute(*(a),a,1,b,c)
-#    define DIR_DELIM_CH '\\'
-#    define PATH_DELIM ";"
-#    define F_RDLCK 0
-#    define F_WRLCK 0
+#  endif
+#  include <windows.h>
+#  define mkdir(a, b) mkdir(a)
+#  define link(src, dst) (CreateHardLink(dst, src, NULL) ? 0 : -1)
+#  define lstat(a, b) stat(a, b)
+#  define execv(a, b) win32execute(a, b, 0, -1, -1)
+#  define execute(a, b, c, d) win32execute(*(a), a, 1, b, c)
+#  define DIR_DELIM_CH '\\'
+#  define PATH_DELIM ";"
+#  define F_RDLCK 0
+#  define F_WRLCK 0
 #else
-#    define DIR_DELIM_CH '/'
-#    define PATH_DELIM ":"
+#  define DIR_DELIM_CH '/'
+#  define PATH_DELIM ":"
 #endif
 
 #ifndef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#  define MAX(a, b) (((a) > (b)) ? (a) : (b))
 #endif
 #ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#  define MIN(a, b) (((a) < (b)) ? (a) : (b))
 #endif
index 8116aa60159ee2de39d45e2c434ebc4d34fbdb40..4ef6665ab9c6dbb2b76f6b85e6d2ba5ea9fa271f 100644 (file)
 
 #include <math.h>
 
-static struct files {
-       char *fname;
-       time_t mtime;
-       uint64_t size;
-} **files;
+struct files
+{
+  char* fname;
+  time_t mtime;
+  uint64_t size;
+};
+
+static struct files** files;
 static unsigned allocated; // Size of the files array.
 static unsigned num_files; // Number of used entries in the files array.
 
@@ -36,76 +39,76 @@ static size_t files_in_cache_threshold;
 
 // File comparison function that orders files in mtime order, oldest first.
 static int
-files_compare(struct files **f1, struct files **f2)
+files_compare(struct files** f1, struct files** f2)
 {
-       if ((*f2)->mtime == (*f1)->mtime) {
-               return strcmp((*f1)->fname, (*f2)->fname);
-       }
-       if ((*f2)->mtime > (*f1)->mtime) {
-               return -1;
-       }
-       return 1;
+  if ((*f2)->mtime == (*f1)->mtime) {
+    return strcmp((*f1)->fname, (*f2)->fname);
+  }
+  if ((*f2)->mtime > (*f1)->mtime) {
+    return -1;
+  }
+  return 1;
 }
 
 // This builds the list of files in the cache.
 static void
-traverse_fn(const char *fname, struct stat *st)
+traverse_fn(const char* fname, struct stat* st)
 {
-       if (!S_ISREG(st->st_mode)) {
-               return;
-       }
-
-       char *p = x_basename(fname);
-       if (str_eq(p, "stats")) {
-               goto out;
-       }
-
-       if (str_startswith(p, ".nfs")) {
-               // Ignore temporary NFS files that may be left for open but deleted files.
-               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")) {
-               goto out;
-       }
-
-       if (num_files == allocated) {
-               allocated = 10000 + num_files*2;
-               files = (struct files **)x_realloc(files, sizeof(struct files *)*allocated);
-       }
-
-       files[num_files] = (struct files *)x_malloc(sizeof(struct files));
-       files[num_files]->fname = x_strdup(fname);
-       files[num_files]->mtime = st->st_mtime;
-       files[num_files]->size = file_size(st);
-       cache_size += files[num_files]->size;
-       files_in_cache++;
-       num_files++;
+  if (!S_ISREG(st->st_mode)) {
+    return;
+  }
+
+  char* p = x_basename(fname);
+  if (str_eq(p, "stats")) {
+    goto out;
+  }
+
+  if (str_startswith(p, ".nfs")) {
+    // Ignore temporary NFS files that may be left for open but deleted files.
+    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")) {
+    goto out;
+  }
+
+  if (num_files == allocated) {
+    allocated = 10000 + num_files * 2;
+    files = (struct files**)x_realloc(files, sizeof(struct files*) * allocated);
+  }
+
+  files[num_files] = (struct files*)x_malloc(sizeof(struct files));
+  files[num_files]->fname = x_strdup(fname);
+  files[num_files]->mtime = st->st_mtime;
+  files[num_files]->size = file_size(st);
+  cache_size += files[num_files]->size;
+  files_in_cache++;
+  num_files++;
 
 out:
-       free(p);
+  free(p);
 }
 
 static void
-delete_file(const char *path, size_t size, bool update_counters)
+delete_file(const charpath, size_t size, bool update_counters)
 {
-       bool deleted = x_try_unlink(path) == 0;
-       if (!deleted && errno != ENOENT && errno != ESTALE) {
-               cc_log("Failed to unlink %s (%s)", path, strerror(errno));
-       } else if (update_counters) {
-               // The counters are intentionally subtracted even if there was no file to
-               // delete since the final cache size calculation will be incorrect if they
-               // aren't. (This can happen when there are several parallel ongoing
-               // cleanups of the same directory.)
-               cache_size -= size;
-               files_in_cache--;
-       }
+  bool deleted = x_try_unlink(path) == 0;
+  if (!deleted && errno != ENOENT && errno != ESTALE) {
+    cc_log("Failed to unlink %s (%s)", path, strerror(errno));
+  } else if (update_counters) {
+    // The counters are intentionally subtracted even if there was no file to
+    // delete since the final cache size calculation will be incorrect if they
+    // aren't. (This can happen when there are several parallel ongoing
+    // cleanups of the same directory.)
+    cache_size -= size;
+    files_in_cache--;
+  }
 }
 
 // Sort the files we've found and delete the oldest ones until we are below the
@@ -113,160 +116,162 @@ delete_file(const char *path, size_t size, bool update_counters)
 static bool
 sort_and_clean(void)
 {
-       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.
-       bool cleaned = false;
-       for (unsigned i = 0; i < num_files; i++) {
-               const char *ext;
-
-               if ((cache_size_threshold == 0
-                    || cache_size <= cache_size_threshold)
-                   && (files_in_cache_threshold == 0
-                       || files_in_cache <= files_in_cache_threshold)) {
-                       break;
-               }
-
-               ext = get_extension(files[i]->fname);
-               if (str_eq(ext, ".stderr")) {
-                       // Make sure that the .o file is deleted before .stderr, because if the
-                       // ccache process gets killed after deleting the .stderr but before
-                       // deleting the .o, the cached result will be inconsistent. (.stderr is
-                       // the only file that is optional; any other file missing from the cache
-                       // will be detected by get_file_from_cache.)
-                       char *base = remove_extension(files[i]->fname);
-                       char *o_file = format("%s.o", base);
-
-                       // Don't subtract this extra deletion from the cache size; that
-                       // bookkeeping will be done when the loop reaches the .o file. If the
-                       // loop doesn't reach the .o file since the target limits have been
-                       // reached, the bookkeeping won't happen, but that small counter
-                       // discrepancy won't do much harm and it will correct itself in the next
-                       // cleanup.
-                       delete_file(o_file, 0, false);
-
-                       free(o_file);
-                       free(base);
-               }
-               delete_file(files[i]->fname, files[i]->size, true);
-               cleaned = true;
-       }
-       return cleaned;
+  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.
+  bool cleaned = false;
+  for (unsigned i = 0; i < num_files; i++) {
+    const char* ext;
+
+    if ((cache_size_threshold == 0 || cache_size <= cache_size_threshold)
+        && (files_in_cache_threshold == 0
+            || files_in_cache <= files_in_cache_threshold)) {
+      break;
+    }
+
+    ext = get_extension(files[i]->fname);
+    if (str_eq(ext, ".stderr")) {
+      // Make sure that the .o file is deleted before .stderr, because if the
+      // ccache process gets killed after deleting the .stderr but before
+      // deleting the .o, the cached result will be inconsistent. (.stderr is
+      // the only file that is optional; any other file missing from the cache
+      // will be detected by get_file_from_cache.)
+      char* base = remove_extension(files[i]->fname);
+      char* o_file = format("%s.o", base);
+
+      // Don't subtract this extra deletion from the cache size; that
+      // bookkeeping will be done when the loop reaches the .o file. If the
+      // loop doesn't reach the .o file since the target limits have been
+      // reached, the bookkeeping won't happen, but that small counter
+      // discrepancy won't do much harm and it will correct itself in the next
+      // cleanup.
+      delete_file(o_file, 0, false);
+
+      free(o_file);
+      free(base);
+    }
+    delete_file(files[i]->fname, files[i]->size, true);
+    cleaned = true;
+  }
+  return cleaned;
 }
 
 // Clean up one cache subdirectory.
 void
-clean_up_dir(struct conf *conf, const char *dir, double limit_multiple)
+clean_up_dir(struct conf* conf, const char* dir, double limit_multiple)
 {
-       cc_log("Cleaning up cache directory %s", dir);
-
-       // When "max files" or "max cache size" is reached, one of the 16 cache
-       // subdirectories is cleaned up. When doing so, files are deleted (in LRU
-       // order) until the levels are below limit_multiple.
-       double cache_size_float = round(conf->max_size * limit_multiple / 16);
-       cache_size_threshold = (uint64_t)cache_size_float;
-       double files_in_cache_float = round(conf->max_files * limit_multiple / 16);
-       files_in_cache_threshold = (size_t)files_in_cache_float;
-
-       num_files = 0;
-       cache_size = 0;
-       files_in_cache = 0;
-
-       // Build a list of files.
-       traverse(dir, traverse_fn);
-
-       // Clean the cache.
-       cc_log("Before cleanup: %.0f KiB, %.0f files",
-              (double)cache_size / 1024,
-              (double)files_in_cache);
-       bool cleaned = sort_and_clean();
-       cc_log("After cleanup: %.0f KiB, %.0f files",
-              (double)cache_size / 1024,
-              (double)files_in_cache);
-
-       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 (unsigned i = 0; i < num_files; i++) {
-               free(files[i]->fname);
-               free(files[i]);
-               files[i] = NULL;
-       }
-       if (files) {
-               free(files);
-       }
-       allocated = 0;
-       files = NULL;
-
-       num_files = 0;
-       cache_size = 0;
-       files_in_cache = 0;
+  cc_log("Cleaning up cache directory %s", dir);
+
+  // When "max files" or "max cache size" is reached, one of the 16 cache
+  // subdirectories is cleaned up. When doing so, files are deleted (in LRU
+  // order) until the levels are below limit_multiple.
+  double cache_size_float = round(conf->max_size * limit_multiple / 16);
+  cache_size_threshold = (uint64_t)cache_size_float;
+  double files_in_cache_float = round(conf->max_files * limit_multiple / 16);
+  files_in_cache_threshold = (size_t)files_in_cache_float;
+
+  num_files = 0;
+  cache_size = 0;
+  files_in_cache = 0;
+
+  // Build a list of files.
+  traverse(dir, traverse_fn);
+
+  // Clean the cache.
+  cc_log("Before cleanup: %.0f KiB, %.0f files",
+         (double)cache_size / 1024,
+         (double)files_in_cache);
+  bool cleaned = sort_and_clean();
+  cc_log("After cleanup: %.0f KiB, %.0f files",
+         (double)cache_size / 1024,
+         (double)files_in_cache);
+
+  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 (unsigned i = 0; i < num_files; i++) {
+    free(files[i]->fname);
+    free(files[i]);
+    files[i] = NULL;
+  }
+  if (files) {
+    free(files);
+  }
+  allocated = 0;
+  files = NULL;
+
+  num_files = 0;
+  cache_size = 0;
+  files_in_cache = 0;
 }
 
 // Clean up all cache subdirectories.
-void clean_up_all(struct conf *conf)
+void
+clean_up_all(struct conf* conf)
 {
-       for (int i = 0; i <= 0xF; i++) {
-               char *dname = format("%s/%1x", conf->cache_dir, i);
-               clean_up_dir(conf, dname, 1.0);
-               free(dname);
-       }
+  for (int i = 0; i <= 0xF; i++) {
+    char* dname = format("%s/%1x", conf->cache_dir, i);
+    clean_up_dir(conf, dname, 1.0);
+    free(dname);
+  }
 }
 
 // Traverse function for wiping files.
-static void wipe_fn(const char *fname, struct stat *st)
+static void
+wipe_fn(const char* fname, struct stat* st)
 {
-       if (!S_ISREG(st->st_mode)) {
-               return;
-       }
+  if (!S_ISREG(st->st_mode)) {
+    return;
+  }
 
-       char *p = x_basename(fname);
-       if (str_eq(p, "stats")) {
-               free(p);
-               return;
-       }
-       free(p);
+  char* p = x_basename(fname);
+  if (str_eq(p, "stats")) {
+    free(p);
+    return;
+  }
+  free(p);
 
-       files_in_cache++;
+  files_in_cache++;
 
-       x_unlink(fname);
+  x_unlink(fname);
 }
 
 // Wipe one cache subdirectory.
 static void
-wipe_dir(const char *dir)
+wipe_dir(const chardir)
 {
-       cc_log("Clearing out cache directory %s", dir);
+  cc_log("Clearing out cache directory %s", dir);
 
-       files_in_cache = 0;
+  files_in_cache = 0;
 
-       traverse(dir, wipe_fn);
+  traverse(dir, wipe_fn);
 
-       if (files_in_cache > 0) {
-               cc_log("Cleared out cache directory %s", dir);
-               stats_add_cleanup(dir, 1);
-       }
+  if (files_in_cache > 0) {
+    cc_log("Cleared out cache directory %s", dir);
+    stats_add_cleanup(dir, 1);
+  }
 
-       files_in_cache = 0;
+  files_in_cache = 0;
 }
 
 // Wipe all cached files in all subdirectories.
-void wipe_all(struct conf *conf)
+void
+wipe_all(struct conf* conf)
 {
-       for (int i = 0; i <= 0xF; i++) {
-               char *dname = format("%s/%1x", conf->cache_dir, i);
-               wipe_dir(dname);
-               free(dname);
-       }
-
-       // Fix the counters.
-       clean_up_all(conf);
+  for (int i = 0; i <= 0xF; i++) {
+    char* dname = format("%s/%1x", conf->cache_dir, i);
+    wipe_dir(dname);
+    free(dname);
+  }
+
+  // Fix the counters.
+  clean_up_all(conf);
 }
index f7f88d0487c726ae285a7f70aabd94ded50b475d..83f3f09cb9df9a89df77423fbadbd56f0e85f6a3 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
+#include "common_header.hpp"
+
 #include "ccache.hpp"
 #include "int_bytes_conversion.hpp"
-#include "common_header.hpp"
 
 bool
-common_header_initialize_for_writing(
-       struct common_header *header,
-       FILE *output,
-       const char magic[4],
-       uint8_t version,
-       uint8_t compression_type,
-       int8_t compression_level,
-       uint64_t content_size,
-       XXH64_state_t *checksum,
-       struct compressor **compressor,
-       struct compr_state **compr_state)
+common_header_initialize_for_writing(struct common_header* header,
+                                     FILE* output,
+                                     const char magic[4],
+                                     uint8_t version,
+                                     uint8_t compression_type,
+                                     int8_t compression_level,
+                                     uint64_t content_size,
+                                     XXH64_state_t* checksum,
+                                     struct compressor** compressor,
+                                     struct compr_state** compr_state)
 {
-       memcpy(header->magic, magic, 4);
-       header->version = version;
-       header->compression_type = compression_type;
-       header->compression_level = compression_level;
-       header->content_size = content_size;
-
-       XXH64_reset(checksum, 0);
-
-       *compressor = compressor_from_type(header->compression_type);
-       assert(*compressor);
-       *compr_state =
-               (*compressor)->init(output, header->compression_level, checksum);
-       if (!*compr_state) {
-               cc_log("Failed to initialize compressor");
-               return false;
-       }
-       header->compression_level =
-               (*compressor)->get_actual_compression_level(*compr_state);
-
-       uint8_t header_bytes[COMMON_HEADER_SIZE];
-       memcpy(header_bytes, header->magic, 4);
-       header_bytes[4] = header->version;
-       header_bytes[5] = header->compression_type;
-       header_bytes[6] = header->compression_level;
-       BYTES_FROM_UINT64(header_bytes + 7, header->content_size);
-       if (fwrite(header_bytes, sizeof(header_bytes), 1, output) != 1) {
-               cc_log("Failed to write common file header");
-               return false;
-       }
-       XXH64_update(checksum, header_bytes, sizeof(header_bytes));
-       return true;
+  memcpy(header->magic, magic, 4);
+  header->version = version;
+  header->compression_type = compression_type;
+  header->compression_level = compression_level;
+  header->content_size = content_size;
+
+  XXH64_reset(checksum, 0);
+
+  *compressor = compressor_from_type(header->compression_type);
+  assert(*compressor);
+  *compr_state =
+    (*compressor)->init(output, header->compression_level, checksum);
+  if (!*compr_state) {
+    cc_log("Failed to initialize compressor");
+    return false;
+  }
+  header->compression_level =
+    (*compressor)->get_actual_compression_level(*compr_state);
+
+  uint8_t header_bytes[COMMON_HEADER_SIZE];
+  memcpy(header_bytes, header->magic, 4);
+  header_bytes[4] = header->version;
+  header_bytes[5] = header->compression_type;
+  header_bytes[6] = header->compression_level;
+  BYTES_FROM_UINT64(header_bytes + 7, header->content_size);
+  if (fwrite(header_bytes, sizeof(header_bytes), 1, output) != 1) {
+    cc_log("Failed to write common file header");
+    return false;
+  }
+  XXH64_update(checksum, header_bytes, sizeof(header_bytes));
+  return true;
 }
 
-bool common_header_initialize_for_reading(
-       struct common_header *header,
-       FILE *input,
-       const char expected_magic[4],
-       uint8_t expected_version,
-       struct decompressor **decompressor,
-       struct decompr_state **decompr_state,
-       XXH64_state_t *checksum,
-       char **errmsg)
+bool
+common_header_initialize_for_reading(struct common_header* header,
+                                     FILE* input,
+                                     const char expected_magic[4],
+                                     uint8_t expected_version,
+                                     struct decompressor** decompressor,
+                                     struct decompr_state** decompr_state,
+                                     XXH64_state_t* checksum,
+                                     char** errmsg)
 {
-       uint8_t header_bytes[COMMON_HEADER_SIZE];
-       if (fread(header_bytes, sizeof(header_bytes), 1, input) != 1) {
-               *errmsg = format("Failed to read common header");
-               return false;
-       }
-
-       memcpy(header->magic, header_bytes, 4);
-       header->version = header_bytes[4];
-       header->compression_type = header_bytes[5];
-       header->compression_level = header_bytes[6];
-       header->content_size = UINT64_FROM_BYTES(header_bytes + 7);
-
-       if (memcmp(header->magic, expected_magic, sizeof(header->magic)) != 0) {
-               *errmsg = format(
-                       "Bad magic value 0x%x%x%x%x",
-                       header->magic[0],
-                       header->magic[1],
-                       header->magic[2],
-                       header->magic[3]);
-               return false;
-       }
-
-       if (header->version != expected_version) {
-               *errmsg = format(
-                       "Unknown version (actual %u, expected %u)",
-                       header->version,
-                       expected_version);
-               return false;
-       }
-
-       if (header->compression_type == COMPR_TYPE_NONE) {
-               // Since we have the size available, let's use it as a super primitive
-               // consistency check for the non-compressed case. (A real checksum is used
-               // for compressed data.)
-               struct stat st;
-               if (x_fstat(fileno(input), &st) != 0) {
-                       return false;
-               }
-               if ((uint64_t)st.st_size != header->content_size) {
-                       *errmsg = format(
-                               "Bad uncompressed file size (actual %llu bytes, expected %llu bytes)",
-                               (unsigned long long)st.st_size,
-                               (unsigned long long)header->content_size);
-                       return false;
-               }
-       }
-
-       if (!decompressor) {
-               return true;
-       }
-
-       *decompressor = decompressor_from_type(header->compression_type);
-       if (!*decompressor) {
-               *errmsg = format(
-                       "Unknown compression type: %u", header->compression_type);
-               return false;
-       }
-
-       if (checksum) {
-               XXH64_reset(checksum, 0);
-               XXH64_update(checksum, header_bytes, sizeof(header_bytes));
-       }
-
-       *decompr_state = (*decompressor)->init(input, checksum);
-       if (!*decompr_state) {
-               *errmsg = x_strdup("Failed to initialize decompressor");
-               return false;
-       }
-
-       return true;
+  uint8_t header_bytes[COMMON_HEADER_SIZE];
+  if (fread(header_bytes, sizeof(header_bytes), 1, input) != 1) {
+    *errmsg = format("Failed to read common header");
+    return false;
+  }
+
+  memcpy(header->magic, header_bytes, 4);
+  header->version = header_bytes[4];
+  header->compression_type = header_bytes[5];
+  header->compression_level = header_bytes[6];
+  header->content_size = UINT64_FROM_BYTES(header_bytes + 7);
+
+  if (memcmp(header->magic, expected_magic, sizeof(header->magic)) != 0) {
+    *errmsg = format("Bad magic value 0x%x%x%x%x",
+                     header->magic[0],
+                     header->magic[1],
+                     header->magic[2],
+                     header->magic[3]);
+    return false;
+  }
+
+  if (header->version != expected_version) {
+    *errmsg = format("Unknown version (actual %u, expected %u)",
+                     header->version,
+                     expected_version);
+    return false;
+  }
+
+  if (header->compression_type == COMPR_TYPE_NONE) {
+    // Since we have the size available, let's use it as a super primitive
+    // consistency check for the non-compressed case. (A real checksum is used
+    // for compressed data.)
+    struct stat st;
+    if (x_fstat(fileno(input), &st) != 0) {
+      return false;
+    }
+    if ((uint64_t)st.st_size != header->content_size) {
+      *errmsg = format(
+        "Bad uncompressed file size (actual %llu bytes, expected %llu bytes)",
+        (unsigned long long)st.st_size,
+        (unsigned long long)header->content_size);
+      return false;
+    }
+  }
+
+  if (!decompressor) {
+    return true;
+  }
+
+  *decompressor = decompressor_from_type(header->compression_type);
+  if (!*decompressor) {
+    *errmsg = format("Unknown compression type: %u", header->compression_type);
+    return false;
+  }
+
+  if (checksum) {
+    XXH64_reset(checksum, 0);
+    XXH64_update(checksum, header_bytes, sizeof(header_bytes));
+  }
+
+  *decompr_state = (*decompressor)->init(input, checksum);
+  if (!*decompr_state) {
+    *errmsg = x_strdup("Failed to initialize decompressor");
+    return false;
+  }
+
+  return true;
 }
 
-void common_header_dump(const struct common_header *header, FILE *f)
+void
+common_header_dump(const struct common_header* header, FILE* f)
 {
-       fprintf(
-               f, "Magic: %c%c%c%c\n",
-               header->magic[0], header->magic[1], header->magic[2], header->magic[3]);
-       fprintf(f, "Version: %u\n", header->version);
-       fprintf(f, "Compression type: %s\n",
-               compression_type_to_string(header->compression_type));
-       fprintf(f, "Compression level: %d\n", header->compression_level);
-       fprintf(f, "Content size: %" PRIu64 "\n", header->content_size);
+  fprintf(f,
+          "Magic: %c%c%c%c\n",
+          header->magic[0],
+          header->magic[1],
+          header->magic[2],
+          header->magic[3]);
+  fprintf(f, "Version: %u\n", header->version);
+  fprintf(f,
+          "Compression type: %s\n",
+          compression_type_to_string(header->compression_type));
+  fprintf(f, "Compression level: %d\n", header->compression_level);
+  fprintf(f, "Content size: %" PRIu64 "\n", header->content_size);
 }
index 05bcda40e70fe4f94e6aa7e6334832b9a7375a16..ae9af69ea9a7c0e08efc21c68437994c9831a1b9 100644 (file)
 #pragma once
 
 #include "compression.hpp"
+
 #include "third_party/xxhash.h"
 
 #define COMMON_HEADER_SIZE 15
 
-struct common_header {
-       char magic[4];
-       uint8_t version;
-       uint8_t compression_type;
-       int8_t compression_level;
-       uint64_t content_size;
+struct common_header
+{
+  char magic[4];
+  uint8_t version;
+  uint8_t compression_type;
+  int8_t compression_level;
+  uint64_t content_size;
 };
 
 // Initialize a common_header and write the header data to a file.
@@ -44,17 +46,16 @@ struct common_header {
 // compressor_state:  State for the compressor.
 // checksum:          Checksum state that will be updated with the written
 //                    bytes.
-bool common_header_initialize_for_writing(
-       struct common_header *header,
-       FILE *output,
-       const char magic[4],
-       uint8_t version,
-       uint8_t compression_type,
-       int8_t compression_level,
-       uint64_t content_size,
-       XXH64_state_t *checksum,
-       struct compressor **compressor,
-       struct compr_state **compr_state);
+bool common_header_initialize_for_writing(struct common_header* header,
+                                          FILE* output,
+                                          const char magic[4],
+                                          uint8_t version,
+                                          uint8_t compression_type,
+                                          int8_t compression_level,
+                                          uint64_t content_size,
+                                          XXH64_state_t* checksum,
+                                          struct compressor** compressor,
+                                          struct compr_state** compr_state);
 
 // Initialize a common_header by reading header data from a file.
 //
@@ -68,14 +69,13 @@ bool common_header_initialize_for_writing(
 //                     decompressor is NULL.
 // checksum:           Checksum state that will be updated with the read bytes.
 //                     May be NULL for no checksumming.
-bool common_header_initialize_for_reading(
-       struct common_header *header,
-       FILE *input,
-       const char expected_magic[4],
-       uint8_t expected_version,
-       struct decompressor **decompressor,
-       struct decompr_state **decompr_state,
-       XXH64_state_t *checksum,
-       char **errmsg);
+bool common_header_initialize_for_reading(struct common_header* header,
+                                          FILE* input,
+                                          const char expected_magic[4],
+                                          uint8_t expected_version,
+                                          struct decompressor** decompressor,
+                                          struct decompr_state** decompr_state,
+                                          XXH64_state_t* checksum,
+                                          char** errmsg);
 
-void common_header_dump(const struct common_header *header, FILE *f);
+void common_header_dump(const struct common_header* header, FILE* f);
index afc46753a472d2b6b96c112e498e5389260d5983..0bb0364513f280b1c8fc13e73a59d0f648990ccb 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "ccache.hpp"
 #include "compopt.hpp"
 
+#include "ccache.hpp"
+
 // The option it too hard to handle at all.
-#define TOO_HARD         (1 << 0)
+#define TOO_HARD (1 << 0)
 
 // The option it too hard for the direct mode.
-#define TOO_HARD_DIRECT  (1 << 1)
+#define TOO_HARD_DIRECT (1 << 1)
 
 // The option takes a separate argument, e.g. "-D FOO=1".
-#define TAKES_ARG        (1 << 2)
+#define TAKES_ARG (1 << 2)
 
 // The option takes a concatenated argument, e.g. "-DFOO=1".
 #define TAKES_CONCAT_ARG (1 << 3)
 
 // The argument to the option is a path that may be rewritten if base_dir is
 // used.
-#define TAKES_PATH       (1 << 4)
+#define TAKES_PATH (1 << 4)
 
 // The option only affects preprocessing; not passed to the compiler if
 // run_second_cpp is false.
-#define AFFECTS_CPP      (1 << 5)
+#define AFFECTS_CPP (1 << 5)
 
 // The option only affects compilation; not passed to the preprocesor.
 #define AFFECTS_COMP (1 << 6)
 
-struct compopt {
-       const char *name;
-       int type;
+struct compopt
+{
+  const char* name;
+  int type;
 };
 
 static const struct compopt compopts[] = {
-       {"--analyze",       TOO_HARD}, // clang
-       {"--compiler-bindir", AFFECTS_CPP | TAKES_ARG}, // nvcc
-       {"--libdevice-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
-       {"--output-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
-       {"--param",         TAKES_ARG},
-       {"--save-temps",    TOO_HARD},
-       {"--save-temps=cwd", TOO_HARD},
-       {"--save-temps=obj", TOO_HARD},
-       {"--serialize-diagnostics", TAKES_ARG | TAKES_PATH},
-       {"-A",              TAKES_ARG},
-       {"-B",              TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-D",              AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
-       {"-E",              TOO_HARD},
-       {"-F",              AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-G",              TAKES_ARG},
-       {"-I",              AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-L",              TAKES_ARG},
-       {"-M",              TOO_HARD},
-       {"-MF",             TAKES_ARG},
-       {"-MJ",             TAKES_ARG | TOO_HARD},
-       {"-MM",             TOO_HARD},
-       {"-MQ",             TAKES_ARG},
-       {"-MT",             TAKES_ARG},
-       {"-P",              TOO_HARD},
-       {"-U",              AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
-       {"-V",              TAKES_ARG},
-       {"-Wa,",            TAKES_CONCAT_ARG | AFFECTS_COMP},
-       {"-Werror",         AFFECTS_COMP}, // don't exit with error when preprocessing
-       {"-Wl,",            TAKES_CONCAT_ARG | AFFECTS_COMP},
-       {"-Xassembler",     TAKES_ARG | TAKES_CONCAT_ARG | AFFECTS_COMP},
-       {"-Xclang",         TAKES_ARG},
-       {"-Xlinker",        TAKES_ARG | TAKES_CONCAT_ARG | AFFECTS_COMP},
-       {"-Xpreprocessor",  AFFECTS_CPP | TOO_HARD_DIRECT | TAKES_ARG},
-       {"-all_load",       AFFECTS_COMP},
-       {"-analyze",        TOO_HARD}, // clang
-       {"-arch",           TAKES_ARG},
-       {"-aux-info",       TAKES_ARG},
-       {"-b",              TAKES_ARG},
-       {"-bind_at_load",   AFFECTS_COMP},
-       {"-bundle",         AFFECTS_COMP},
-       {"-ccbin",          AFFECTS_CPP | TAKES_ARG}, // nvcc
-       {"-fmodules",       TOO_HARD},
-       {"-fno-working-directory", AFFECTS_CPP},
-       {"-fplugin=libcc1plugin", TOO_HARD}, // interaction with GDB
-       {"-frepo",          TOO_HARD},
-       {"-ftime-trace",    TOO_HARD}, // clang
-       {"-fworking-directory", AFFECTS_CPP},
-       {"-gtoggle",        TOO_HARD},
-       {"-idirafter",      AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-iframework",     AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-imacros",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-imultilib",      AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-include",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-include-pch",    AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-install_name",   TAKES_ARG}, // Darwin linker option
-       {"-iprefix",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-iquote",         AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-isysroot",       AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-isystem",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-iwithprefix",    AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-iwithprefixbefore",
-        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
-       {"-ldir",           AFFECTS_CPP | TAKES_ARG}, // nvcc
-       {"-nolibc",         AFFECTS_COMP},
-       {"-nostdinc",       AFFECTS_CPP},
-       {"-nostdinc++",     AFFECTS_CPP},
-       {"-odir",           AFFECTS_CPP | TAKES_ARG}, // nvcc
-       {"-pie",            AFFECTS_COMP},
-       {"-prebind",        AFFECTS_COMP},
-       {"-preload",        AFFECTS_COMP},
-       {"-rdynamic",       AFFECTS_COMP},
-       {"-remap",          AFFECTS_CPP},
-       {"-save-temps",     TOO_HARD},
-       {"-save-temps=cwd", TOO_HARD},
-       {"-save-temps=obj", TOO_HARD},
-       {"-stdlib=",        AFFECTS_CPP | TAKES_CONCAT_ARG},
-       {"-trigraphs",      AFFECTS_CPP},
-       {"-u",              TAKES_ARG | TAKES_CONCAT_ARG},
+  {"--analyze", TOO_HARD},                            // clang
+  {"--compiler-bindir", AFFECTS_CPP | TAKES_ARG},     // nvcc
+  {"--libdevice-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
+  {"--output-directory", AFFECTS_CPP | TAKES_ARG},    // nvcc
+  {"--param", TAKES_ARG},
+  {"--save-temps", TOO_HARD},
+  {"--save-temps=cwd", TOO_HARD},
+  {"--save-temps=obj", TOO_HARD},
+  {"--serialize-diagnostics", TAKES_ARG | TAKES_PATH},
+  {"-A", TAKES_ARG},
+  {"-B", TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-D", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
+  {"-E", TOO_HARD},
+  {"-F", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-G", TAKES_ARG},
+  {"-I", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-L", TAKES_ARG},
+  {"-M", TOO_HARD},
+  {"-MF", TAKES_ARG},
+  {"-MJ", TAKES_ARG | TOO_HARD},
+  {"-MM", TOO_HARD},
+  {"-MQ", TAKES_ARG},
+  {"-MT", TAKES_ARG},
+  {"-P", TOO_HARD},
+  {"-U", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
+  {"-V", TAKES_ARG},
+  {"-Wa,", TAKES_CONCAT_ARG | AFFECTS_COMP},
+  {"-Werror", AFFECTS_COMP}, // don't exit with error when preprocessing
+  {"-Wl,", TAKES_CONCAT_ARG | AFFECTS_COMP},
+  {"-Xassembler", TAKES_ARG | TAKES_CONCAT_ARG | AFFECTS_COMP},
+  {"-Xclang", TAKES_ARG},
+  {"-Xlinker", TAKES_ARG | TAKES_CONCAT_ARG | AFFECTS_COMP},
+  {"-Xpreprocessor", AFFECTS_CPP | TOO_HARD_DIRECT | TAKES_ARG},
+  {"-all_load", AFFECTS_COMP},
+  {"-analyze", TOO_HARD}, // clang
+  {"-arch", TAKES_ARG},
+  {"-aux-info", TAKES_ARG},
+  {"-b", TAKES_ARG},
+  {"-bind_at_load", AFFECTS_COMP},
+  {"-bundle", AFFECTS_COMP},
+  {"-ccbin", AFFECTS_CPP | TAKES_ARG}, // nvcc
+  {"-fmodules", TOO_HARD},
+  {"-fno-working-directory", AFFECTS_CPP},
+  {"-fplugin=libcc1plugin", TOO_HARD}, // interaction with GDB
+  {"-frepo", TOO_HARD},
+  {"-ftime-trace", TOO_HARD}, // clang
+  {"-fworking-directory", AFFECTS_CPP},
+  {"-gtoggle", TOO_HARD},
+  {"-idirafter", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-iframework", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-imacros", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-imultilib", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-include", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-include-pch", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-install_name", TAKES_ARG}, // Darwin linker option
+  {"-iprefix", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-iquote", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-isysroot", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-isystem", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-iwithprefix", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-iwithprefixbefore",
+   AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+  {"-ldir", AFFECTS_CPP | TAKES_ARG}, // nvcc
+  {"-nolibc", AFFECTS_COMP},
+  {"-nostdinc", AFFECTS_CPP},
+  {"-nostdinc++", AFFECTS_CPP},
+  {"-odir", AFFECTS_CPP | TAKES_ARG}, // nvcc
+  {"-pie", AFFECTS_COMP},
+  {"-prebind", AFFECTS_COMP},
+  {"-preload", AFFECTS_COMP},
+  {"-rdynamic", AFFECTS_COMP},
+  {"-remap", AFFECTS_CPP},
+  {"-save-temps", TOO_HARD},
+  {"-save-temps=cwd", TOO_HARD},
+  {"-save-temps=obj", TOO_HARD},
+  {"-stdlib=", AFFECTS_CPP | TAKES_CONCAT_ARG},
+  {"-trigraphs", AFFECTS_CPP},
+  {"-u", TAKES_ARG | TAKES_CONCAT_ARG},
 };
 
-
 static int
-compare_compopts(const void *key1, const void *key2)
+compare_compopts(const void* key1, const void* key2)
 {
-       const struct compopt *opt1 = (const struct compopt *)key1;
-       const struct compopt *opt2 = (const struct compopt *)key2;
-       return strcmp(opt1->name, opt2->name);
+  const struct compopt* opt1 = (const struct compopt*)key1;
+  const struct compopt* opt2 = (const struct compopt*)key2;
+  return strcmp(opt1->name, opt2->name);
 }
 
 static int
-compare_prefix_compopts(const void *key1, const void *key2)
+compare_prefix_compopts(const void* key1, const void* key2)
 {
-       const struct compopt *opt1 = (const struct compopt *)key1;
-       const struct compopt *opt2 = (const struct compopt *)key2;
-       return strncmp(opt1->name, opt2->name, strlen(opt2->name));
+  const struct compopt* opt1 = (const struct compopt*)key1;
+  const struct compopt* opt2 = (const struct compopt*)key2;
+  return strncmp(opt1->name, opt2->name, strlen(opt2->name));
 }
 
-static const struct compopt *
-find(const char *option)
+static const struct compopt*
+find(const charoption)
 {
-       struct compopt key;
-       key.name = option;
-       void* result = bsearch(
-               &key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]),
-               compare_compopts);
-       return static_cast<compopt*>(result);
+  struct compopt key;
+  key.name = option;
+  void* result = bsearch(&key,
+                         compopts,
+                         ARRAY_SIZE(compopts),
+                         sizeof(compopts[0]),
+                         compare_compopts);
+  return static_cast<compopt*>(result);
 }
 
-static const struct compopt *
-find_prefix(const char *option)
+static const struct compopt*
+find_prefix(const charoption)
 {
-       struct compopt key;
-       key.name = option;
-       void* result = bsearch(
-               &key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]),
-               compare_prefix_compopts);
-       return static_cast<compopt*>(result);
+  struct compopt key;
+  key.name = option;
+  void* result = bsearch(&key,
+                         compopts,
+                         ARRAY_SIZE(compopts),
+                         sizeof(compopts[0]),
+                         compare_prefix_compopts);
+  return static_cast<compopt*>(result);
 }
 
 // Runs fn on the first two characters of option.
 bool
-compopt_short(bool (*fn)(const char *), const char *option)
+compopt_short(bool (*fn)(const char*), const char* option)
 {
-       char *short_opt = x_strndup(option, 2);
-       bool retval = fn(short_opt);
-       free(short_opt);
-       return retval;
+  char* short_opt = x_strndup(option, 2);
+  bool retval = fn(short_opt);
+  free(short_opt);
+  return retval;
 }
 
 // Used by unittest/test_compopt.c.
@@ -184,83 +189,83 @@ bool compopt_verify_sortedness(void);
 bool
 compopt_verify_sortedness(void)
 {
-       for (size_t i = 1; i < ARRAY_SIZE(compopts); i++) {
-               if (strcmp(compopts[i-1].name, compopts[i].name) >= 0) {
-                       fprintf(stderr,
-                               "compopt_verify_sortedness: %s >= %s\n",
-                               compopts[i-1].name,
-                               compopts[i].name);
-                       return false;
-               }
-       }
-       return true;
+  for (size_t i = 1; i < ARRAY_SIZE(compopts); i++) {
+    if (strcmp(compopts[i - 1].name, compopts[i].name) >= 0) {
+      fprintf(stderr,
+              "compopt_verify_sortedness: %s >= %s\n",
+              compopts[i - 1].name,
+              compopts[i].name);
+      return false;
+    }
+  }
+  return true;
 }
 
 bool
-compopt_affects_cpp(const char *option)
+compopt_affects_cpp(const charoption)
 {
-       const struct compopt *co = find(option);
-       return co && (co->type & AFFECTS_CPP);
+  const struct compopt* co = find(option);
+  return co && (co->type & AFFECTS_CPP);
 }
 
 bool
-compopt_affects_comp(const char *option)
+compopt_affects_comp(const charoption)
 {
-       const struct compopt *co = find(option);
-       return co && (co->type & AFFECTS_COMP);
+  const struct compopt* co = find(option);
+  return co && (co->type & AFFECTS_COMP);
 }
 
 bool
-compopt_too_hard(const char *option)
+compopt_too_hard(const charoption)
 {
-       const struct compopt *co = find(option);
-       return co && (co->type & TOO_HARD);
+  const struct compopt* co = find(option);
+  return co && (co->type & TOO_HARD);
 }
 
 bool
-compopt_too_hard_for_direct_mode(const char *option)
+compopt_too_hard_for_direct_mode(const charoption)
 {
-       const struct compopt *co = find(option);
-       return co && (co->type & TOO_HARD_DIRECT);
+  const struct compopt* co = find(option);
+  return co && (co->type & TOO_HARD_DIRECT);
 }
 
 bool
-compopt_takes_path(const char *option)
+compopt_takes_path(const charoption)
 {
-       const struct compopt *co = find(option);
-       return co && (co->type & TAKES_PATH);
+  const struct compopt* co = find(option);
+  return co && (co->type & TAKES_PATH);
 }
 
 bool
-compopt_takes_arg(const char *option)
+compopt_takes_arg(const charoption)
 {
-       const struct compopt *co = find(option);
-       return co && (co->type & TAKES_ARG);
+  const struct compopt* co = find(option);
+  return co && (co->type & TAKES_ARG);
 }
 
 bool
-compopt_takes_concat_arg(const char *option)
+compopt_takes_concat_arg(const charoption)
 {
-       const struct compopt *co = find(option);
-       return co && (co->type & TAKES_CONCAT_ARG);
+  const struct compopt* co = find(option);
+  return co && (co->type & TAKES_CONCAT_ARG);
 }
 
 // Determines if the prefix of the option matches any option and affects the
 // preprocessor.
 bool
-compopt_prefix_affects_cpp(const char *option)
+compopt_prefix_affects_cpp(const charoption)
 {
-       // Prefix options have to take concatenated args.
-       const struct compopt *co = find_prefix(option);
-       return co && (co->type & TAKES_CONCAT_ARG) && (co->type & AFFECTS_CPP);
+  // Prefix options have to take concatenated args.
+  const struct compopt* co = find_prefix(option);
+  return co && (co->type & TAKES_CONCAT_ARG) && (co->type & AFFECTS_CPP);
 }
 
 // Determines if the prefix of the option matches any option and affects the
 // preprocessor.
 bool
-compopt_prefix_affects_comp(const char *option)
+compopt_prefix_affects_comp(const charoption)
 {
-       // Prefix options have to take concatenated args.
-       const struct compopt *co = find_prefix(option);
-       return co && (co->type & TAKES_CONCAT_ARG) && (co->type & AFFECTS_COMP);
+  // Prefix options have to take concatenated args.
+  const struct compopt* co = find_prefix(option);
+  return co && (co->type & TAKES_CONCAT_ARG) && (co->type & AFFECTS_COMP);
 }
index 97157c976003b70fd8ee67ecfe8604151b768ed7..bb65369497bff81abc2f403fc9a82fb07dbe02ce 100644 (file)
 
 #include "system.hpp"
 
-bool compopt_short(bool (*fn)(const char *option), const char *option);
-bool compopt_affects_cpp(const char *option);
-bool compopt_affects_comp(const char *option);
-bool compopt_too_hard(const char *option);
-bool compopt_too_hard_for_direct_mode(const char *option);
-bool compopt_takes_path(const char *option);
-bool compopt_takes_arg(const char *option);
-bool compopt_takes_concat_arg(const char *option);
-bool compopt_prefix_affects_cpp(const char *option);
-bool compopt_prefix_affects_comp(const char *option);
+bool compopt_short(bool (*fn)(const char* option), const char* option);
+bool compopt_affects_cpp(const charoption);
+bool compopt_affects_comp(const charoption);
+bool compopt_too_hard(const charoption);
+bool compopt_too_hard_for_direct_mode(const charoption);
+bool compopt_takes_path(const charoption);
+bool compopt_takes_arg(const charoption);
+bool compopt_takes_concat_arg(const charoption);
+bool compopt_prefix_affects_cpp(const charoption);
+bool compopt_prefix_affects_comp(const charoption);
index 7d5cfa91f1e3c6ffea15f0668359955b694e1e16..7093d3aa2b10b2edf2d4cb6e1613e71c729a8b19 100644 (file)
 
 #include "compression.hpp"
 
-struct state {
-       FILE *output;
-       XXH64_state_t *checksum;
+struct state
+{
+  FILE* output;
+  XXH64_state_t* checksum;
 };
 
-static struct compr_state *
-compr_none_init(FILE *output, int8_t level, XXH64_state_t *checksum)
+static struct compr_state*
+compr_none_init(FILE* output, int8_t level, XXH64_state_t* checksum)
 {
-       auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
-       state->output = output;
-       state->checksum = checksum;
-       (void)level;
-       return (struct compr_state *)state;
+  auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
+  state->output = output;
+  state->checksum = checksum;
+  (void)level;
+  return (struct compr_state*)state;
 }
 
 static int8_t
-compr_none_get_actual_compression_level(struct compr_state *handle)
+compr_none_get_actual_compression_level(struct compr_statehandle)
 {
-       (void)handle;
-       return 0;
+  (void)handle;
+  return 0;
 }
 
 static bool
-compr_none_write(struct compr_state *handle, const void *data, size_t size)
+compr_none_write(struct compr_state* handle, const void* data, size_t size)
 {
-       struct state *state = (struct state *)handle;
-       size_t ret = fwrite(data, size, 1, state->output);
-       if (state->checksum) {
-               XXH64_update(state->checksum, data, size);
-       }
-       return ret == 1;
+  struct state* state = (struct state*)handle;
+  size_t ret = fwrite(data, size, 1, state->output);
+  if (state->checksum) {
+    XXH64_update(state->checksum, data, size);
+  }
+  return ret == 1;
 }
 
 static bool
-compr_none_free(struct compr_state *handle)
+compr_none_free(struct compr_statehandle)
 {
-       struct state *state = (struct state *)handle;
-       bool result = ferror(state->output) == 0;
-       free(state);
-       return result;
+  struct state* state = (struct state*)handle;
+  bool result = ferror(state->output) == 0;
+  free(state);
+  return result;
 }
 
 struct compressor compressor_none_impl = {
-       compr_none_init,
-       compr_none_get_actual_compression_level,
-       compr_none_write,
-       compr_none_free
-};
+  compr_none_init,
+  compr_none_get_actual_compression_level,
+  compr_none_write,
+  compr_none_free};
index 873b9e7f98dce9e8426af90a2a182279ad62f334..005c3f0e728e01e3a92d88e7803b5ab09e98071b 100644 (file)
 
 #define DEFAULT_ZSTD_COMPRESSION_LEVEL -1
 
-struct state {
-       FILE *output;
-       XXH64_state_t *checksum;
-       ZSTD_CStream *stream;
-       ZSTD_inBuffer in;
-       ZSTD_outBuffer out;
-       bool failed;
-       int8_t compression_level;
+struct state
+{
+  FILE* output;
+  XXH64_state_t* checksum;
+  ZSTD_CStream* stream;
+  ZSTD_inBuffer in;
+  ZSTD_outBuffer out;
+  bool failed;
+  int8_t compression_level;
 };
 
-static struct compr_state *
-compr_zstd_init(FILE *output, int8_t level, XXH64_state_t *checksum)
+static struct compr_state*
+compr_zstd_init(FILE* output, int8_t level, XXH64_state_t* checksum)
 {
-       auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
-       state->output = output;
-       state->checksum = checksum;
-       state->stream = ZSTD_createCStream();
-       state->failed = false;
-
-       if (level == 0) {
-               level = DEFAULT_ZSTD_COMPRESSION_LEVEL;
-               cc_log("Using default compression level %d", level);
-       }
-
-       // libzstd 1.3.4 and newer support negative levels. However, the query
-       // function ZSTD_minCLevel did not appear until 1.3.6, so perform detection
-       // based on version instead.
-       if (ZSTD_versionNumber() < 10304 && level < 1) {
-               cc_log(
-                       "Using compression level 1 (minimum level supported by libzstd) instead"
-                       " of %d",
-                       level);
-               level = 1;
-       }
-
-       state->compression_level = MIN(level, ZSTD_maxCLevel());
-       if (state->compression_level != level) {
-               cc_log(
-                       "Using compression level %d (max libzstd level) instead of %d",
-                       state->compression_level,
-                       level);
-       }
-
-       size_t ret = ZSTD_initCStream(state->stream, state->compression_level);
-       if (ZSTD_isError(ret)) {
-               ZSTD_freeCStream(state->stream);
-               free(state);
-               return NULL;
-       }
-       return (struct compr_state *)state;
+  auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
+  state->output = output;
+  state->checksum = checksum;
+  state->stream = ZSTD_createCStream();
+  state->failed = false;
+
+  if (level == 0) {
+    level = DEFAULT_ZSTD_COMPRESSION_LEVEL;
+    cc_log("Using default compression level %d", level);
+  }
+
+  // libzstd 1.3.4 and newer support negative levels. However, the query
+  // function ZSTD_minCLevel did not appear until 1.3.6, so perform detection
+  // based on version instead.
+  if (ZSTD_versionNumber() < 10304 && level < 1) {
+    cc_log(
+      "Using compression level 1 (minimum level supported by libzstd) instead"
+      " of %d",
+      level);
+    level = 1;
+  }
+
+  state->compression_level = MIN(level, ZSTD_maxCLevel());
+  if (state->compression_level != level) {
+    cc_log("Using compression level %d (max libzstd level) instead of %d",
+           state->compression_level,
+           level);
+  }
+
+  size_t ret = ZSTD_initCStream(state->stream, state->compression_level);
+  if (ZSTD_isError(ret)) {
+    ZSTD_freeCStream(state->stream);
+    free(state);
+    return NULL;
+  }
+  return (struct compr_state*)state;
 }
 
 static int8_t
-compr_zstd_get_actual_compression_level(struct compr_state *handle)
+compr_zstd_get_actual_compression_level(struct compr_statehandle)
 {
-       struct state *state = (struct state *)handle;
-       return state->compression_level;
+  struct state* state = (struct state*)handle;
+  return state->compression_level;
 }
 
 static bool
-compr_zstd_write(struct compr_state *handle, const void *data, size_t size)
+compr_zstd_write(struct compr_state* handle, const void* data, size_t size)
 {
-       if (!handle) {
-               return false;
-       }
-       struct state *state = (struct state *)handle;
-
-       if (state->checksum) {
-               XXH64_update(state->checksum, data, size);
-       }
-
-       state->in.src = data;
-       state->in.size = size;
-       state->in.pos = 0;
-
-       int flush = data ? 0 : 1;
-
-       size_t ret;
-       while (state->in.pos < state->in.size) {
-               unsigned char buffer[READ_BUFFER_SIZE];
-               state->out.dst = buffer;
-               state->out.size = sizeof(buffer);
-               state->out.pos = 0;
-               ret = ZSTD_compressStream(state->stream, &state->out, &state->in);
-               assert(!(ZSTD_isError(ret)));
-               size_t compressed_bytes = state->out.pos;
-               if (fwrite(buffer, 1, compressed_bytes, state->output) != compressed_bytes
-                   || ferror(state->output)) {
-                       state->failed = true;
-                       return false;
-               }
-       }
-       ret = flush;
-       while (ret > 0) {
-               unsigned char buffer[READ_BUFFER_SIZE];
-               state->out.dst = buffer;
-               state->out.size = sizeof(buffer);
-               state->out.pos = 0;
-               ret = ZSTD_endStream(state->stream, &state->out);
-               size_t compressed_bytes = state->out.pos;
-               if (fwrite(buffer, 1, compressed_bytes, state->output) != compressed_bytes
-                   || ferror(state->output)) {
-                       state->failed = true;
-                       return false;
-               }
-       }
-
-       return true;
+  if (!handle) {
+    return false;
+  }
+  struct state* state = (struct state*)handle;
+
+  if (state->checksum) {
+    XXH64_update(state->checksum, data, size);
+  }
+
+  state->in.src = data;
+  state->in.size = size;
+  state->in.pos = 0;
+
+  int flush = data ? 0 : 1;
+
+  size_t ret;
+  while (state->in.pos < state->in.size) {
+    unsigned char buffer[READ_BUFFER_SIZE];
+    state->out.dst = buffer;
+    state->out.size = sizeof(buffer);
+    state->out.pos = 0;
+    ret = ZSTD_compressStream(state->stream, &state->out, &state->in);
+    assert(!(ZSTD_isError(ret)));
+    size_t compressed_bytes = state->out.pos;
+    if (fwrite(buffer, 1, compressed_bytes, state->output) != compressed_bytes
+        || ferror(state->output)) {
+      state->failed = true;
+      return false;
+    }
+  }
+  ret = flush;
+  while (ret > 0) {
+    unsigned char buffer[READ_BUFFER_SIZE];
+    state->out.dst = buffer;
+    state->out.size = sizeof(buffer);
+    state->out.pos = 0;
+    ret = ZSTD_endStream(state->stream, &state->out);
+    size_t compressed_bytes = state->out.pos;
+    if (fwrite(buffer, 1, compressed_bytes, state->output) != compressed_bytes
+        || ferror(state->output)) {
+      state->failed = true;
+      return false;
+    }
+  }
+
+  return true;
 }
 
 static bool
-compr_zstd_free(struct compr_state *handle)
+compr_zstd_free(struct compr_statehandle)
 {
-       if (!handle) {
-               return false;
-       }
+  if (!handle) {
+    return false;
+  }
 
-       struct state *state = (struct state *)handle;
+  struct state* state = (struct state*)handle;
 
-       compr_zstd_write(handle, NULL, 0);
-       ZSTD_freeCStream(state->stream);
-       bool success = !state->failed;
-       free(state);
-       return success;
+  compr_zstd_write(handle, NULL, 0);
+  ZSTD_freeCStream(state->stream);
+  bool success = !state->failed;
+  free(state);
+  return success;
 }
 
 struct compressor compressor_zstd_impl = {
-       compr_zstd_init,
-       compr_zstd_get_actual_compression_level,
-       compr_zstd_write,
-       compr_zstd_free
-};
+  compr_zstd_init,
+  compr_zstd_get_actual_compression_level,
+  compr_zstd_write,
+  compr_zstd_free};
index e9299058e9ec5370f749b3e90a2fffe31527933d..d7656fc9ddb0668d27f8137bb859470917414102 100644 (file)
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 #include "ccache.hpp"
-
 #include "common_header.hpp"
 #include "manifest.hpp"
 #include "result.hpp"
 
 static bool
-get_content_size(
-       const char *path, const char *magic, uint8_t version, size_t *size)
+get_content_size(const char* path,
+                 const char* magic,
+                 uint8_t version,
+                 size_t* size)
 {
-       char *errmsg;
-       FILE *f = fopen(path, "rb");
-       if (!f) {
-               cc_log("Failed to open %s for reading: %s", path, strerror(errno));
-               return false;
-       }
-       struct common_header header;
-       bool success = common_header_initialize_for_reading(
-               &header,
-               f,
-               magic,
-               version,
-               NULL,
-               NULL,
-               NULL,
-               &errmsg);
-       fclose(f);
-       if (success) {
-               *size = header.content_size;
-       }
-
-       return success;
+  char* errmsg;
+  FILE* f = fopen(path, "rb");
+  if (!f) {
+    cc_log("Failed to open %s for reading: %s", path, strerror(errno));
+    return false;
+  }
+  struct common_header header;
+  bool success = common_header_initialize_for_reading(
+    &header, f, magic, version, NULL, NULL, NULL, &errmsg);
+  fclose(f);
+  if (success) {
+    *size = header.content_size;
+  }
+
+  return success;
 }
 
 static uint64_t on_disk_size;
@@ -57,93 +51,96 @@ static uint64_t incompr_size;
 
 // This measures the size of files in the cache.
 static void
-measure_fn(const char *fname, struct stat *st)
+measure_fn(const char* fname, struct stat* st)
 {
-       if (!S_ISREG(st->st_mode)) {
-               return;
-       }
-
-       char *p = x_basename(fname);
-       if (str_eq(p, "stats")) {
-               free(p);
-               return;
-       }
-
-       if (str_startswith(p, ".nfs")) {
-               // Ignore temporary NFS files that may be left for open but deleted files.
-               free(p);
-               return;
-       }
-
-       if (strstr(p, ".tmp.")) {
-               // Ignore tmp files since they are transient.
-               free(p);
-               return;
-       }
-
-       if (strstr(p, "CACHEDIR.TAG")) {
-               free(p);
-               return;
-       }
-
-       free(p);
-
-       on_disk_size += file_size(st);
-
-       size_t content_size = 0;
-       const char *file_ext = get_extension(p);
-       bool is_compressible = false;
-       if (str_eq(file_ext, ".manifest")) {
-               is_compressible = get_content_size(
-                       fname, MANIFEST_MAGIC, MANIFEST_VERSION, &content_size);
-       } else if (str_eq(file_ext, ".result")) {
-               is_compressible = get_content_size(
-                       fname, RESULT_MAGIC, RESULT_VERSION, &content_size);
-       }
-
-       if (is_compressible) {
-               compr_size += st->st_size;
-               compr_orig_size += content_size;
-       } else {
-               incompr_size += st->st_size;
-       }
+  if (!S_ISREG(st->st_mode)) {
+    return;
+  }
+
+  char* p = x_basename(fname);
+  if (str_eq(p, "stats")) {
+    free(p);
+    return;
+  }
+
+  if (str_startswith(p, ".nfs")) {
+    // Ignore temporary NFS files that may be left for open but deleted files.
+    free(p);
+    return;
+  }
+
+  if (strstr(p, ".tmp.")) {
+    // Ignore tmp files since they are transient.
+    free(p);
+    return;
+  }
+
+  if (strstr(p, "CACHEDIR.TAG")) {
+    free(p);
+    return;
+  }
+
+  free(p);
+
+  on_disk_size += file_size(st);
+
+  size_t content_size = 0;
+  const char* file_ext = get_extension(p);
+  bool is_compressible = false;
+  if (str_eq(file_ext, ".manifest")) {
+    is_compressible =
+      get_content_size(fname, MANIFEST_MAGIC, MANIFEST_VERSION, &content_size);
+  } else if (str_eq(file_ext, ".result")) {
+    is_compressible =
+      get_content_size(fname, RESULT_MAGIC, RESULT_VERSION, &content_size);
+  }
+
+  if (is_compressible) {
+    compr_size += st->st_size;
+    compr_orig_size += content_size;
+  } else {
+    incompr_size += st->st_size;
+  }
 }
 
 // Process up all cache subdirectories.
-void compress_stats(struct conf *conf)
+void
+compress_stats(struct conf* conf)
 {
-       on_disk_size = 0;
-       compr_size = 0;
-       compr_orig_size = 0;
-       incompr_size = 0;
-
-       for (int i = 0; i <= 0xF; i++) {
-               char *dname = format("%s/%1x", conf->cache_dir, i);
-               traverse(dname, measure_fn);
-               free(dname);
-       }
-
-       double ratio = compr_size > 0 ? ((double) compr_orig_size) / compr_size : 0.0;
-       double savings = ratio > 0.0 ? 100.0 - (100.0 / ratio) : 0.0;
-
-       char *on_disk_size_str = format_human_readable_size(on_disk_size);
-       char *cache_size_str = format_human_readable_size(compr_size + incompr_size);
-       char *compr_size_str = format_human_readable_size(compr_size);
-       char *compr_orig_size_str = format_human_readable_size(compr_orig_size);
-       char *incompr_size_str = format_human_readable_size(incompr_size);
-
-       printf("Total data:            %8s (%s disk blocks)\n",
-              cache_size_str, on_disk_size_str);
-       printf("Compressible data:     %8s (%.1f%% of original size)\n",
-              compr_size_str, 100.0 - savings);
-       printf("  - Original size:     %8s\n", compr_orig_size_str);
-       printf("  - Compression ratio: %5.3f x  (%.1f%% space savings)\n",
-              ratio, savings);
-       printf("Incompressible data:   %8s\n", incompr_size_str);
-
-       free(incompr_size_str);
-       free(compr_orig_size_str);
-       free(compr_size_str);
-       free(cache_size_str);
-       free(on_disk_size_str);
+  on_disk_size = 0;
+  compr_size = 0;
+  compr_orig_size = 0;
+  incompr_size = 0;
+
+  for (int i = 0; i <= 0xF; i++) {
+    char* dname = format("%s/%1x", conf->cache_dir, i);
+    traverse(dname, measure_fn);
+    free(dname);
+  }
+
+  double ratio = compr_size > 0 ? ((double)compr_orig_size) / compr_size : 0.0;
+  double savings = ratio > 0.0 ? 100.0 - (100.0 / ratio) : 0.0;
+
+  char* on_disk_size_str = format_human_readable_size(on_disk_size);
+  char* cache_size_str = format_human_readable_size(compr_size + incompr_size);
+  char* compr_size_str = format_human_readable_size(compr_size);
+  char* compr_orig_size_str = format_human_readable_size(compr_orig_size);
+  char* incompr_size_str = format_human_readable_size(incompr_size);
+
+  printf("Total data:            %8s (%s disk blocks)\n",
+         cache_size_str,
+         on_disk_size_str);
+  printf("Compressible data:     %8s (%.1f%% of original size)\n",
+         compr_size_str,
+         100.0 - savings);
+  printf("  - Original size:     %8s\n", compr_orig_size_str);
+  printf(
+    "  - Compression ratio: %5.3f x  (%.1f%% space savings)\n", ratio, savings);
+  printf("Incompressible data:   %8s\n", incompr_size_str);
+
+  free(incompr_size_str);
+  free(compr_orig_size_str);
+  free(compr_size_str);
+  free(cache_size_str);
+  free(on_disk_size_str);
 }
index f210541fad11596734bc1e7e9399fab7c65f6dc4..766c45cf3eefdc12ccd0b598a40bc0b18bf4b149 100644 (file)
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 #include "compression.hpp"
+
 #include "conf.hpp"
 
-extern struct conf *conf;
+extern struct confconf;
 
-int8_t compression_level_from_config(void)
+int8_t
+compression_level_from_config(void)
 {
-       return conf->compression ? conf->compression_level : 0;
+  return conf->compression ? conf->compression_level : 0;
 }
 
-enum compression_type compression_type_from_config(void)
+enum compression_type
+compression_type_from_config(void)
 {
-       return conf->compression ? COMPR_TYPE_ZSTD : COMPR_TYPE_NONE;
+  return conf->compression ? COMPR_TYPE_ZSTD : COMPR_TYPE_NONE;
 }
 
-const char *compression_type_to_string(uint8_t type)
+const char*
+compression_type_to_string(uint8_t type)
 {
-       switch (type) {
-       case COMPR_TYPE_NONE:
-               return "none";
+  switch (type) {
+  case COMPR_TYPE_NONE:
+    return "none";
 
-       case COMPR_TYPE_ZSTD:
-               return "zstd";
-       }
+  case COMPR_TYPE_ZSTD:
+    return "zstd";
+  }
 
-       return "unknown";
+  return "unknown";
 }
 
-struct compressor *compressor_from_type(uint8_t type)
+struct compressor*
+compressor_from_type(uint8_t type)
 {
-       switch (type) {
-       case COMPR_TYPE_NONE:
-               return &compressor_none_impl;
+  switch (type) {
+  case COMPR_TYPE_NONE:
+    return &compressor_none_impl;
 
-       case COMPR_TYPE_ZSTD:
-               return &compressor_zstd_impl;
-       }
+  case COMPR_TYPE_ZSTD:
+    return &compressor_zstd_impl;
+  }
 
-       return NULL;
+  return NULL;
 }
 
-struct decompressor *decompressor_from_type(uint8_t type)
+struct decompressor*
+decompressor_from_type(uint8_t type)
 {
-       switch (type) {
-       case COMPR_TYPE_NONE:
-               return &decompressor_none_impl;
+  switch (type) {
+  case COMPR_TYPE_NONE:
+    return &decompressor_none_impl;
 
-       case COMPR_TYPE_ZSTD:
-               return &decompressor_zstd_impl;
-       }
+  case COMPR_TYPE_ZSTD:
+    return &decompressor_zstd_impl;
+  }
 
-       return NULL;
+  return NULL;
 }
index b48be164367781b8e18eef4ca5bde78818f7f5aa..93514a71103c1f334c247f3935b119597ec98d19 100644 (file)
 #pragma once
 
 #include "system.hpp"
+
 #include "third_party/xxhash.h"
 
 struct compr_state;
 
-struct compressor {
-       // Create and initialize a compressor.
-       //
-       // output: The file to write compressed data to.
-       // compression_level: Desired compression level.
-       // checksum: Checksum state to update (NULL for no checksum).
-       struct compr_state *(*init)(
-               FILE *output,
-               int8_t compression_level,
-               XXH64_state_t *checksum);
-
-       // Get the actual compression level that will be used.
-       int8_t (*get_actual_compression_level)(struct compr_state *state);
-
-       // Compress data.
-       //
-       // data: Buffer to read decompressed data from.
-       // size: How many bytes to read.
-       //
-       // Returns false on failure, otherwise true.
-       bool (*write)(struct compr_state *state, const void *data, size_t size);
-
-       // Finalize compressor and free its state.
-       //
-       // Returns false if finalization failed or if any previous operation failed,
-       // otherwise true.
-       bool (*free)(struct compr_state *state);
+struct compressor
+{
+  // Create and initialize a compressor.
+  //
+  // output: The file to write compressed data to.
+  // compression_level: Desired compression level.
+  // checksum: Checksum state to update (NULL for no checksum).
+  struct compr_state* (*init)(FILE* output,
+                              int8_t compression_level,
+                              XXH64_state_t* checksum);
+
+  // Get the actual compression level that will be used.
+  int8_t (*get_actual_compression_level)(struct compr_state* state);
+
+  // Compress data.
+  //
+  // data: Buffer to read decompressed data from.
+  // size: How many bytes to read.
+  //
+  // Returns false on failure, otherwise true.
+  bool (*write)(struct compr_state* state, const void* data, size_t size);
+
+  // Finalize compressor and free its state.
+  //
+  // Returns false if finalization failed or if any previous operation failed,
+  // otherwise true.
+  bool (*free)(struct compr_state* state);
 };
 
 struct decompr_state;
 
-struct decompressor {
-       // Create and initialize a decompressor.
-       //
-       // input: The file to read compressed data from.
-       // checksum: Checksum state to update (NULL for no checksum).
-       struct decompr_state *(*init)(FILE *input, XXH64_state_t *checksum);
-
-       // Decompress data.
-       //
-       // data: Buffer to write decompressed data to.
-       // size: How many bytes to write.
-       //
-       // Returns false on failure, otherwise true.
-       bool (*read)(struct decompr_state *state, void *data, size_t size);
-
-       // Finalize the decompressor and free its state.
-       //
-       // Returns false if finalization failed or if any previous operation failed,
-       // otherwise true.
-       bool (*free)(struct decompr_state *state);
-};
+struct decompressor
+{
+  // Create and initialize a decompressor.
+  //
+  // input: The file to read compressed data from.
+  // checksum: Checksum state to update (NULL for no checksum).
+  struct decompr_state* (*init)(FILE* input, XXH64_state_t* checksum);
+
+  // Decompress data.
+  //
+  // data: Buffer to write decompressed data to.
+  // size: How many bytes to write.
+  //
+  // Returns false on failure, otherwise true.
+  bool (*read)(struct decompr_state* state, void* data, size_t size);
 
-enum compression_type {
-       COMPR_TYPE_NONE = 0,
-       COMPR_TYPE_ZSTD = 1
+  // Finalize the decompressor and free its state.
+  //
+  // Returns false if finalization failed or if any previous operation failed,
+  // otherwise true.
+  bool (*free)(struct decompr_state* state);
 };
 
+enum compression_type { COMPR_TYPE_NONE = 0, COMPR_TYPE_ZSTD = 1 };
+
 extern struct compressor compressor_none_impl;
 extern struct decompressor decompressor_none_impl;
 
@@ -89,6 +88,6 @@ extern struct decompressor decompressor_zstd_impl;
 
 int8_t compression_level_from_config(void);
 enum compression_type compression_type_from_config(void);
-const char *compression_type_to_string(uint8_t type);
-struct compressor *compressor_from_type(uint8_t type);
-struct decompressor *decompressor_from_type(uint8_t type);
+const charcompression_type_to_string(uint8_t type);
+struct compressorcompressor_from_type(uint8_t type);
+struct decompressordecompressor_from_type(uint8_t type);
index 379a23156e7c835d7c546f2f10eedcb857c7116c..bf0a454d4655c097edd8bd8620b4d9dc66d99fac 100644 (file)
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 #include "conf.hpp"
+
+#include "ccache.hpp"
 #include "confitems.hpp"
 #include "envtoconfitems.hpp"
-#include "ccache.hpp"
 
 enum handle_conf_result {
-       HANDLE_CONF_OK,
-       HANDLE_CONF_UNKNOWN,
-       HANDLE_CONF_FAIL
+  HANDLE_CONF_OK,
+  HANDLE_CONF_UNKNOWN,
+  HANDLE_CONF_FAIL
 };
 
-static const struct conf_item *
-find_conf(const char *name)
+static const struct conf_item*
+find_conf(const charname)
 {
-       return confitems_get(name, strlen(name));
+  return confitems_get(name, strlen(name));
 }
 
-static const struct env_to_conf_item *
-find_env_to_conf(const char *name)
+static const struct env_to_conf_item*
+find_env_to_conf(const charname)
 {
-       return envtoconfitems_get(name, strlen(name));
+  return envtoconfitems_get(name, strlen(name));
 }
 
 static enum handle_conf_result
-handle_conf_setting(struct conf *conf, const char *key, const char *value,
-                    char **errmsg, bool from_env_variable, bool negate_boolean,
-                    const char *origin)
+handle_conf_setting(struct conf* conf,
+                    const char* key,
+                    const char* value,
+                    char** errmsg,
+                    bool from_env_variable,
+                    bool negate_boolean,
+                    const char* origin)
 {
-       const struct conf_item *item = find_conf(key);
-       if (!item) {
-               return HANDLE_CONF_UNKNOWN;
-       }
-
-       if (from_env_variable && item->parser == confitem_parse_bool) {
-               // Special rule for boolean settings from the environment: "0", "false",
-               // "disable" and "no" (case insensitive) are invalid, and all other values
-               // mean true.
-               //
-               // Previously any value meant true, but this was surprising to users, who
-               // might do something like CCACHE_DISABLE=0 and expect ccache to be
-               // enabled.
-               if (str_eq(value, "0") || strcasecmp(value, "false") == 0
-                   || strcasecmp(value, "disable") == 0 || strcasecmp(value, "no") == 0) {
-                       fatal("invalid boolean environment variable value \"%s\"", value);
-               }
-
-               bool *boolvalue = (bool *)((char *)conf + item->offset);
-               *boolvalue = !negate_boolean;
-               goto out;
-       }
-
-       if (!item->parser(value, (char *)conf + item->offset, errmsg)) {
-               return HANDLE_CONF_FAIL;
-       }
-       if (item->verifier && !item->verifier((char *)conf + item->offset, errmsg)) {
-               return HANDLE_CONF_FAIL;
-       }
+  const struct conf_item* item = find_conf(key);
+  if (!item) {
+    return HANDLE_CONF_UNKNOWN;
+  }
+
+  if (from_env_variable && item->parser == confitem_parse_bool) {
+    // Special rule for boolean settings from the environment: "0", "false",
+    // "disable" and "no" (case insensitive) are invalid, and all other values
+    // mean true.
+    //
+    // Previously any value meant true, but this was surprising to users, who
+    // might do something like CCACHE_DISABLE=0 and expect ccache to be
+    // enabled.
+    if (str_eq(value, "0") || strcasecmp(value, "false") == 0
+        || strcasecmp(value, "disable") == 0 || strcasecmp(value, "no") == 0) {
+      fatal("invalid boolean environment variable value \"%s\"", value);
+    }
+
+    bool* boolvalue = (bool*)((char*)conf + item->offset);
+    *boolvalue = !negate_boolean;
+    goto out;
+  }
+
+  if (!item->parser(value, (char*)conf + item->offset, errmsg)) {
+    return HANDLE_CONF_FAIL;
+  }
+  if (item->verifier && !item->verifier((char*)conf + item->offset, errmsg)) {
+    return HANDLE_CONF_FAIL;
+  }
 
 out:
-       conf->item_origins[item->number] = origin;
-       return HANDLE_CONF_OK;
+  conf->item_origins[item->number] = origin;
+  return HANDLE_CONF_OK;
 }
 
 static bool
-parse_line(const char *line, char **key, char **value, char **errmsg)
+parse_line(const char* line, char** key, char** value, char** errmsg)
 {
-#define SKIP_WS(x) do { while (isspace(*x)) { ++x; } } while (false)
-
-       *key = NULL;
-       *value = NULL;
-
-       const char *p = line;
-       SKIP_WS(p);
-       if (*p == '\0' || *p == '#') {
-               return true;
-       }
-       const char *q = p;
-       while (isalpha(*q) || *q == '_') {
-               ++q;
-       }
-       *key = x_strndup(p, q - p);
-       p = q;
-       SKIP_WS(p);
-       if (*p != '=') {
-               *errmsg = x_strdup("missing equal sign");
-               free(*key);
-               *key = NULL;
-               return false;
-       }
-       ++p;
-
-       // Skip leading whitespace.
-       SKIP_WS(p);
-       q = p;
-       while (*q) {
-               ++q;
-       }
-       // Skip trailing whitespace.
-       while (isspace(q[-1])) {
-               --q;
-       }
-       *value = x_strndup(p, q - p);
-
-       return true;
+#define SKIP_WS(x)                                                             \
+  do {                                                                         \
+    while (isspace(*x)) {                                                      \
+      ++x;                                                                     \
+    }                                                                          \
+  } while (false)
+
+  *key = NULL;
+  *value = NULL;
+
+  const char* p = line;
+  SKIP_WS(p);
+  if (*p == '\0' || *p == '#') {
+    return true;
+  }
+  const char* q = p;
+  while (isalpha(*q) || *q == '_') {
+    ++q;
+  }
+  *key = x_strndup(p, q - p);
+  p = q;
+  SKIP_WS(p);
+  if (*p != '=') {
+    *errmsg = x_strdup("missing equal sign");
+    free(*key);
+    *key = NULL;
+    return false;
+  }
+  ++p;
+
+  // Skip leading whitespace.
+  SKIP_WS(p);
+  q = p;
+  while (*q) {
+    ++q;
+  }
+  // Skip trailing whitespace.
+  while (isspace(q[-1])) {
+    --q;
+  }
+  *value = x_strndup(p, q - p);
+
+  return true;
 
 #undef SKIP_WS
 }
 
 // Create a conf struct with default values.
-struct conf *
+struct conf*
 conf_create(void)
 {
-       auto conf = static_cast<struct conf*>(x_malloc(sizeof(struct conf)));
-
-       conf->base_dir = x_strdup("");
-       conf->cache_dir = format("%s/.ccache", get_home_directory());
-       conf->cache_dir_levels = 2;
-       conf->compiler = x_strdup("");
-       conf->compiler_check = x_strdup("mtime");
-       conf->compression = true;
-       conf->compression_level = 0;
-       conf->cpp_extension = x_strdup("");
-       conf->debug = false;
-       conf->depend_mode = false;
-       conf->direct_mode = true;
-       conf->disable = false;
-       conf->extra_files_to_hash = x_strdup("");
-       conf->file_clone = false;
-       conf->hard_link = false;
-       conf->hash_dir = true;
-       conf->ignore_headers_in_manifest = x_strdup("");
-       conf->keep_comments_cpp = false;
-       conf->limit_multiple = 0.8;
-       conf->log_file = x_strdup("");
-       conf->max_files = 0;
-       conf->max_size = (uint64_t)5 * 1000 * 1000 * 1000;
-       conf->path = x_strdup("");
-       conf->pch_external_checksum = false;
-       conf->prefix_command = x_strdup("");
-       conf->prefix_command_cpp = x_strdup("");
-       conf->read_only = false;
-       conf->read_only_direct = false;
-       conf->recache = false;
-       conf->run_second_cpp = true;
-       conf->sloppiness = 0;
-       conf->stats = true;
-       conf->temporary_dir = x_strdup("");
-       conf->umask = UINT_MAX; // Default: don't set umask.
-       conf->unify = false;
-
-       conf->item_origins = static_cast<const char**>(
-               x_malloc(confitems_count() * sizeof(char *)));
-       for (size_t i = 0; i < confitems_count(); ++i) {
-               conf->item_origins[i] = "default";
-       }
-       return conf;
+  auto conf = static_cast<struct conf*>(x_malloc(sizeof(struct conf)));
+
+  conf->base_dir = x_strdup("");
+  conf->cache_dir = format("%s/.ccache", get_home_directory());
+  conf->cache_dir_levels = 2;
+  conf->compiler = x_strdup("");
+  conf->compiler_check = x_strdup("mtime");
+  conf->compression = true;
+  conf->compression_level = 0;
+  conf->cpp_extension = x_strdup("");
+  conf->debug = false;
+  conf->depend_mode = false;
+  conf->direct_mode = true;
+  conf->disable = false;
+  conf->extra_files_to_hash = x_strdup("");
+  conf->file_clone = false;
+  conf->hard_link = false;
+  conf->hash_dir = true;
+  conf->ignore_headers_in_manifest = x_strdup("");
+  conf->keep_comments_cpp = false;
+  conf->limit_multiple = 0.8;
+  conf->log_file = x_strdup("");
+  conf->max_files = 0;
+  conf->max_size = (uint64_t)5 * 1000 * 1000 * 1000;
+  conf->path = x_strdup("");
+  conf->pch_external_checksum = false;
+  conf->prefix_command = x_strdup("");
+  conf->prefix_command_cpp = x_strdup("");
+  conf->read_only = false;
+  conf->read_only_direct = false;
+  conf->recache = false;
+  conf->run_second_cpp = true;
+  conf->sloppiness = 0;
+  conf->stats = true;
+  conf->temporary_dir = x_strdup("");
+  conf->umask = UINT_MAX; // Default: don't set umask.
+  conf->unify = false;
+
+  conf->item_origins =
+    static_cast<const char**>(x_malloc(confitems_count() * sizeof(char*)));
+  for (size_t i = 0; i < confitems_count(); ++i) {
+    conf->item_origins[i] = "default";
+  }
+  return conf;
 }
 
 void
-conf_free(struct conf *conf)
+conf_free(struct confconf)
 {
-       if (!conf) {
-               return;
-       }
-       free(conf->base_dir);
-       free(conf->cache_dir);
-       free(conf->compiler);
-       free(conf->compiler_check);
-       free(conf->cpp_extension);
-       free(conf->extra_files_to_hash);
-       free(conf->ignore_headers_in_manifest);
-       free(conf->log_file);
-       free(conf->path);
-       free(conf->prefix_command);
-       free(conf->prefix_command_cpp);
-       free(conf->temporary_dir);
-       free((void *)conf->item_origins); // Workaround for MSVC warning
-       free(conf);
+  if (!conf) {
+    return;
+  }
+  free(conf->base_dir);
+  free(conf->cache_dir);
+  free(conf->compiler);
+  free(conf->compiler_check);
+  free(conf->cpp_extension);
+  free(conf->extra_files_to_hash);
+  free(conf->ignore_headers_in_manifest);
+  free(conf->log_file);
+  free(conf->path);
+  free(conf->prefix_command);
+  free(conf->prefix_command_cpp);
+  free(conf->temporary_dir);
+  free((void*)conf->item_origins); // Workaround for MSVC warning
+  free(conf);
 }
 
 // Note: The path pointer is stored in conf, so path must outlive conf.
@@ -201,241 +211,249 @@ conf_free(struct conf *conf)
 // On failure, if an I/O error occurred errno is set appropriately, otherwise
 // errno is set to zero indicating that config itself was invalid.
 bool
-conf_read(struct conf *conf, const char *path, char **errmsg)
+conf_read(struct conf* conf, const char* path, char** errmsg)
 {
-       assert(errmsg);
-       *errmsg = NULL;
-
-       FILE *f = fopen(path, "r");
-       if (!f) {
-               *errmsg = format("%s: %s", path, strerror(errno));
-               return false;
-       }
-
-       unsigned line_number = 0;
-       bool result = true;
-       char buf[10000];
-       while (fgets(buf, sizeof(buf), f)) {
-               ++line_number;
-
-               char *key;
-               char *value;
-               char *errmsg2;
-               enum handle_conf_result hcr = HANDLE_CONF_OK;
-               bool ok = parse_line(buf, &key, &value, &errmsg2);
-               if (ok && key) { // key == NULL if comment or blank line.
-                       hcr =
-                               handle_conf_setting(conf, key, value, &errmsg2, false, false, path);
-                       ok = hcr != HANDLE_CONF_FAIL; // unknown is OK
-               }
-               free(key);
-               free(value);
-               if (!ok) {
-                       *errmsg = format("%s:%u: %s", path, line_number, errmsg2);
-                       free(errmsg2);
-                       errno = 0;
-                       result = false;
-                       goto out;
-               }
-       }
-       if (ferror(f)) {
-               *errmsg = x_strdup(strerror(errno));
-               result = false;
-       }
+  assert(errmsg);
+  *errmsg = NULL;
+
+  FILE* f = fopen(path, "r");
+  if (!f) {
+    *errmsg = format("%s: %s", path, strerror(errno));
+    return false;
+  }
+
+  unsigned line_number = 0;
+  bool result = true;
+  char buf[10000];
+  while (fgets(buf, sizeof(buf), f)) {
+    ++line_number;
+
+    char* key;
+    char* value;
+    char* errmsg2;
+    enum handle_conf_result hcr = HANDLE_CONF_OK;
+    bool ok = parse_line(buf, &key, &value, &errmsg2);
+    if (ok && key) { // key == NULL if comment or blank line.
+      hcr = handle_conf_setting(conf, key, value, &errmsg2, false, false, path);
+      ok = hcr != HANDLE_CONF_FAIL; // unknown is OK
+    }
+    free(key);
+    free(value);
+    if (!ok) {
+      *errmsg = format("%s:%u: %s", path, line_number, errmsg2);
+      free(errmsg2);
+      errno = 0;
+      result = false;
+      goto out;
+    }
+  }
+  if (ferror(f)) {
+    *errmsg = x_strdup(strerror(errno));
+    result = false;
+  }
 
 out:
-       fclose(f);
-       return result;
+  fclose(f);
+  return result;
 }
 
 bool
-conf_update_from_environment(struct conf *conf, char **errmsg)
+conf_update_from_environment(struct conf* conf, char** errmsg)
 {
-       for (char **p = environ; *p; ++p) {
-               if (!str_startswith(*p, "CCACHE_")) {
-                       continue;
-               }
-               char *q = strchr(*p, '=');
-               if (!q) {
-                       continue;
-               }
-
-               bool negate;
-               size_t key_start;
-               if (str_startswith(*p + 7, "NO")) {
-                       negate = true;
-                       key_start = 9;
-               } else {
-                       negate = false;
-                       key_start = 7;
-               }
-               char *key = x_strndup(*p + key_start, q - *p - key_start);
-
-               ++q; // Now points to the value.
-
-               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 = NULL;
-               enum handle_conf_result hcr = handle_conf_setting(
-                       conf, env_to_conf_item->conf_name, q, &errmsg2, true, negate,
-                       "environment");
-               if (hcr != HANDLE_CONF_OK) {
-                       *errmsg = format("%s: %s", key, errmsg2);
-                       free(errmsg2);
-                       free(key);
-                       return false;
-               }
-
-               free(key);
-       }
-
-       return true;
+  for (char** p = environ; *p; ++p) {
+    if (!str_startswith(*p, "CCACHE_")) {
+      continue;
+    }
+    char* q = strchr(*p, '=');
+    if (!q) {
+      continue;
+    }
+
+    bool negate;
+    size_t key_start;
+    if (str_startswith(*p + 7, "NO")) {
+      negate = true;
+      key_start = 9;
+    } else {
+      negate = false;
+      key_start = 7;
+    }
+    char* key = x_strndup(*p + key_start, q - *p - key_start);
+
+    ++q; // Now points to the value.
+
+    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 = NULL;
+    enum handle_conf_result hcr =
+      handle_conf_setting(conf,
+                          env_to_conf_item->conf_name,
+                          q,
+                          &errmsg2,
+                          true,
+                          negate,
+                          "environment");
+    if (hcr != HANDLE_CONF_OK) {
+      *errmsg = format("%s: %s", key, errmsg2);
+      free(errmsg2);
+      free(key);
+      return false;
+    }
+
+    free(key);
+  }
+
+  return true;
 }
 
 bool
-conf_set_value_in_file(const char *path, const char *key, const char *value,
-                       char **errmsg)
+conf_set_value_in_file(const char* path,
+                       const char* key,
+                       const char* value,
+                       char** errmsg)
 {
-       const struct conf_item *item = find_conf(key);
-       if (!item) {
-               *errmsg = format("unknown configuration option \"%s\"", key);
-               return false;
-       }
-
-       char dummy[8] = {0}; // The maximum entry size in struct conf.
-       if (!item->parser(value, (void *)dummy, errmsg)
-           || (item->verifier && !item->verifier(value, errmsg))) {
-               return false;
-       }
-
-       FILE *infile = fopen(path, "r");
-       if (!infile) {
-               *errmsg = format("%s: %s", path, strerror(errno));
-               return false;
-       }
-
-       char *outpath = format("%s.tmp", path);
-       FILE *outfile = create_tmp_file(&outpath, "w");
-       if (!outfile) {
-               *errmsg = format("%s: %s", outpath, strerror(errno));
-               free(outpath);
-               fclose(infile);
-               return false;
-       }
-
-       bool found = false;
-       char buf[10000];
-       while (fgets(buf, sizeof(buf), infile)) {
-               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);
-               } else {
-                       fputs(buf, outfile);
-               }
-               free(key2);
-               free(value2);
-       }
-
-       if (!found) {
-               fprintf(outfile, "%s = %s\n", key, value);
-       }
-
-       fclose(infile);
-       fclose(outfile);
-       if (x_rename(outpath, path) != 0) {
-               *errmsg = format("rename %s to %s: %s", outpath, path, strerror(errno));
-               return false;
-       }
-       free(outpath);
-
-       return true;
+  const struct conf_item* item = find_conf(key);
+  if (!item) {
+    *errmsg = format("unknown configuration option \"%s\"", key);
+    return false;
+  }
+
+  char dummy[8] = {0}; // The maximum entry size in struct conf.
+  if (!item->parser(value, (void*)dummy, errmsg)
+      || (item->verifier && !item->verifier(value, errmsg))) {
+    return false;
+  }
+
+  FILE* infile = fopen(path, "r");
+  if (!infile) {
+    *errmsg = format("%s: %s", path, strerror(errno));
+    return false;
+  }
+
+  char* outpath = format("%s.tmp", path);
+  FILE* outfile = create_tmp_file(&outpath, "w");
+  if (!outfile) {
+    *errmsg = format("%s: %s", outpath, strerror(errno));
+    free(outpath);
+    fclose(infile);
+    return false;
+  }
+
+  bool found = false;
+  char buf[10000];
+  while (fgets(buf, sizeof(buf), infile)) {
+    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);
+    } else {
+      fputs(buf, outfile);
+    }
+    free(key2);
+    free(value2);
+  }
+
+  if (!found) {
+    fprintf(outfile, "%s = %s\n", key, value);
+  }
+
+  fclose(infile);
+  fclose(outfile);
+  if (x_rename(outpath, path) != 0) {
+    *errmsg = format("rename %s to %s: %s", outpath, path, strerror(errno));
+    return false;
+  }
+  free(outpath);
+
+  return true;
 }
 
 bool
-conf_print_value(struct conf *conf, const char *key,
-                 FILE *file, char **errmsg)
+conf_print_value(struct conf* conf, const char* key, FILE* file, char** errmsg)
 {
-       const struct conf_item *item = find_conf(key);
-       if (!item) {
-               *errmsg = format("unknown configuration option \"%s\"", key);
-               return false;
-       }
-       void *value = (char *)conf + item->offset;
-       char *str = item->formatter(value);
-       fprintf(file, "%s\n", str);
-       free(str);
-       return true;
+  const struct conf_item* item = find_conf(key);
+  if (!item) {
+    *errmsg = format("unknown configuration option \"%s\"", key);
+    return false;
+  }
+  void* value = (char*)conf + item->offset;
+  char* str = item->formatter(value);
+  fprintf(file, "%s\n", str);
+  free(str);
+  return true;
 }
 
 static bool
-print_item(struct conf *conf, const char *key,
-           void (*printer)(const char *descr, const char *origin,
-                           void *context),
-           void *context)
+print_item(struct conf* conf,
+           const char* key,
+           void (*printer)(const char* descr,
+                           const char* origin,
+                           void* context),
+           void* context)
 {
-       const struct conf_item *item = find_conf(key);
-       if (!item) {
-               return false;
-       }
-       void *value = (char *)conf + item->offset;
-       char *str = item->formatter(value);
-       char *buf = x_strdup("");
-       reformat(&buf, "%s = %s", key, str);
-       printer(buf, conf->item_origins[item->number], context);
-       free(buf);
-       free(str);
-       return true;
+  const struct conf_item* item = find_conf(key);
+  if (!item) {
+    return false;
+  }
+  void* value = (char*)conf + item->offset;
+  char* str = item->formatter(value);
+  char* buf = x_strdup("");
+  reformat(&buf, "%s = %s", key, str);
+  printer(buf, conf->item_origins[item->number], context);
+  free(buf);
+  free(str);
+  return true;
 }
 
 bool
-conf_print_items(struct conf *conf,
-                 void (*printer)(const char *descr, const char *origin,
-                                 void *context),
-                 void *context)
+conf_print_items(struct conf* conf,
+                 void (*printer)(const char* descr,
+                                 const char* origin,
+                                 void* context),
+                 void* context)
 {
-       bool ok = true;
-       ok &= print_item(conf, "base_dir", printer, context);
-       ok &= print_item(conf, "cache_dir", printer, context);
-       ok &= print_item(conf, "cache_dir_levels", printer, context);
-       ok &= print_item(conf, "compiler", printer, context);
-       ok &= print_item(conf, "compiler_check", printer, context);
-       ok &= print_item(conf, "compression", printer, context);
-       ok &= print_item(conf, "compression_level", printer, context);
-       ok &= print_item(conf, "cpp_extension", printer, context);
-       ok &= print_item(conf, "debug", printer, context);
-       ok &= print_item(conf, "depend_mode", printer, context);
-       ok &= print_item(conf, "direct_mode", printer, context);
-       ok &= print_item(conf, "disable", printer, context);
-       ok &= print_item(conf, "extra_files_to_hash", printer, context);
-       ok &= print_item(conf, "file_clone", printer, context);
-       ok &= print_item(conf, "hard_link", printer, context);
-       ok &= print_item(conf, "hash_dir", printer, context);
-       ok &= print_item(conf, "ignore_headers_in_manifest", printer, context);
-       ok &= print_item(conf, "keep_comments_cpp", printer, context);
-       ok &= print_item(conf, "limit_multiple", printer, context);
-       ok &= print_item(conf, "log_file", printer, context);
-       ok &= print_item(conf, "max_files", printer, context);
-       ok &= print_item(conf, "max_size", printer, context);
-       ok &= print_item(conf, "path", printer, context);
-       ok &= print_item(conf, "pch_external_checksum", printer, context);
-       ok &= print_item(conf, "prefix_command", printer, context);
-       ok &= print_item(conf, "prefix_command_cpp", printer, context);
-       ok &= print_item(conf, "read_only", printer, context);
-       ok &= print_item(conf, "read_only_direct", printer, context);
-       ok &= print_item(conf, "recache", printer, context);
-       ok &= print_item(conf, "run_second_cpp", printer, context);
-       ok &= print_item(conf, "sloppiness", printer, context);
-       ok &= print_item(conf, "stats", printer, context);
-       ok &= print_item(conf, "temporary_dir", printer, context);
-       ok &= print_item(conf, "umask", printer, context);
-       ok &= print_item(conf, "unify", printer, context);
-       return ok;
+  bool ok = true;
+  ok &= print_item(conf, "base_dir", printer, context);
+  ok &= print_item(conf, "cache_dir", printer, context);
+  ok &= print_item(conf, "cache_dir_levels", printer, context);
+  ok &= print_item(conf, "compiler", printer, context);
+  ok &= print_item(conf, "compiler_check", printer, context);
+  ok &= print_item(conf, "compression", printer, context);
+  ok &= print_item(conf, "compression_level", printer, context);
+  ok &= print_item(conf, "cpp_extension", printer, context);
+  ok &= print_item(conf, "debug", printer, context);
+  ok &= print_item(conf, "depend_mode", printer, context);
+  ok &= print_item(conf, "direct_mode", printer, context);
+  ok &= print_item(conf, "disable", printer, context);
+  ok &= print_item(conf, "extra_files_to_hash", printer, context);
+  ok &= print_item(conf, "file_clone", printer, context);
+  ok &= print_item(conf, "hard_link", printer, context);
+  ok &= print_item(conf, "hash_dir", printer, context);
+  ok &= print_item(conf, "ignore_headers_in_manifest", printer, context);
+  ok &= print_item(conf, "keep_comments_cpp", printer, context);
+  ok &= print_item(conf, "limit_multiple", printer, context);
+  ok &= print_item(conf, "log_file", printer, context);
+  ok &= print_item(conf, "max_files", printer, context);
+  ok &= print_item(conf, "max_size", printer, context);
+  ok &= print_item(conf, "path", printer, context);
+  ok &= print_item(conf, "pch_external_checksum", printer, context);
+  ok &= print_item(conf, "prefix_command", printer, context);
+  ok &= print_item(conf, "prefix_command_cpp", printer, context);
+  ok &= print_item(conf, "read_only", printer, context);
+  ok &= print_item(conf, "read_only_direct", printer, context);
+  ok &= print_item(conf, "recache", printer, context);
+  ok &= print_item(conf, "run_second_cpp", printer, context);
+  ok &= print_item(conf, "sloppiness", printer, context);
+  ok &= print_item(conf, "stats", printer, context);
+  ok &= print_item(conf, "temporary_dir", printer, context);
+  ok &= print_item(conf, "umask", printer, context);
+  ok &= print_item(conf, "unify", printer, context);
+  return ok;
 }
index 792d48a9b0b90834eaf4f6991e24f7f005a4dccf..54c27f03c9c35a138877dc774145c2ed2ae5730c 100644 (file)
 
 #include "system.hpp"
 
-struct conf {
-       char *base_dir;
-       char *cache_dir;
-       unsigned cache_dir_levels;
-       char *compiler;
-       char *compiler_check;
-       bool compression;
-       int compression_level;
-       char *cpp_extension;
-       bool debug;
-       bool depend_mode;
-       bool direct_mode;
-       bool disable;
-       char *extra_files_to_hash;
-       bool file_clone;
-       bool hard_link;
-       bool hash_dir;
-       char *ignore_headers_in_manifest;
-       bool keep_comments_cpp;
-       double limit_multiple;
-       char *log_file;
-       unsigned max_files;
-       uint64_t max_size;
-       char *path;
-       bool pch_external_checksum;
-       char *prefix_command;
-       char *prefix_command_cpp;
-       bool read_only;
-       bool read_only_direct;
-       bool recache;
-       bool run_second_cpp;
-       unsigned sloppiness;
-       bool stats;
-       char *temporary_dir;
-       unsigned umask;
-       bool unify;
+struct conf
+{
+  char* base_dir;
+  char* cache_dir;
+  unsigned cache_dir_levels;
+  char* compiler;
+  char* compiler_check;
+  bool compression;
+  int compression_level;
+  char* cpp_extension;
+  bool debug;
+  bool depend_mode;
+  bool direct_mode;
+  bool disable;
+  char* extra_files_to_hash;
+  bool file_clone;
+  bool hard_link;
+  bool hash_dir;
+  char* ignore_headers_in_manifest;
+  bool keep_comments_cpp;
+  double limit_multiple;
+  char* log_file;
+  unsigned max_files;
+  uint64_t max_size;
+  char* path;
+  bool pch_external_checksum;
+  char* prefix_command;
+  char* prefix_command_cpp;
+  bool read_only;
+  bool read_only_direct;
+  bool recache;
+  bool run_second_cpp;
+  unsigned sloppiness;
+  bool stats;
+  char* temporary_dir;
+  unsigned umask;
+  bool unify;
 
-       const char **item_origins;
+  const char** item_origins;
 };
 
-struct conf *conf_create(void);
-void conf_free(struct conf *conf);
-bool conf_read(struct conf *conf, const char *path, char **errmsg);
-bool conf_update_from_environment(struct conf *conf, char **errmsg);
-bool conf_print_value(struct conf *conf, const char *key,
-                      FILE *file, char **errmsg);
-bool conf_set_value_in_file(const char *path, const char *key,
-                            const char *value, char **errmsg);
-bool conf_print_items(struct conf *conf,
-                      void (*printer)(const char *descr, const char *origin,
-                                      void *context),
-                      void *context);
+struct conf* conf_create(void);
+void conf_free(struct conf* conf);
+bool conf_read(struct conf* conf, const char* path, char** errmsg);
+bool conf_update_from_environment(struct conf* conf, char** errmsg);
+bool
+conf_print_value(struct conf* conf, const char* key, FILE* file, char** errmsg);
+bool conf_set_value_in_file(const char* path,
+                            const char* key,
+                            const char* value,
+                            char** errmsg);
+bool conf_print_items(struct conf* conf,
+                      void (*printer)(const char* descr,
+                                      const char* origin,
+                                      void* context),
+                      void* context);
index 1b4023f496171896713fb61b13021b1f1862fdf7..386a430f91c746b37e2e2f40af732a9cf5d84ddb 100644 (file)
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 #include "confitems.hpp"
+
 #include "ccache.hpp"
 
-static char *
-format_string(const void *value)
+static char*
+format_string(const voidvalue)
 {
-       const char *const *str = (const char *const *)value;
-       return x_strdup(*str);
+  const char* const* str = (const char* const*)value;
+  return x_strdup(*str);
 }
 
 bool
-confitem_parse_bool(const char *str, void *result, char **errmsg)
+confitem_parse_bool(const char* str, void* result, char** errmsg)
 {
-       bool *value = (bool *)result;
+  bool* value = (bool*)result;
 
-       if (str_eq(str, "true")) {
-               *value = true;
-               return true;
-       } else if (str_eq(str, "false")) {
-               *value = false;
-               return true;
-       } else {
-               *errmsg = format("not a boolean value: \"%s\"", str);
-               return false;
-       }
+  if (str_eq(str, "true")) {
+    *value = true;
+    return true;
+  } else if (str_eq(str, "false")) {
+    *value = false;
+    return true;
+  } else {
+    *errmsg = format("not a boolean value: \"%s\"", str);
+    return false;
+  }
 }
 
-char *
-confitem_format_bool(const void *value)
+char*
+confitem_format_bool(const voidvalue)
 {
-       const bool *b = (const bool *)value;
-       return x_strdup(*b ? "true" : "false");
+  const bool* b = (const bool*)value;
+  return x_strdup(*b ? "true" : "false");
 }
 
 bool
-confitem_parse_env_string(const char *str, void *result, char **errmsg)
+confitem_parse_env_string(const char* str, void* result, char** errmsg)
 {
-       char **value = (char **)result;
-       free(*value);
-       *value = subst_env_in_string(str, errmsg);
-       return *value != NULL;
+  char** value = (char**)result;
+  free(*value);
+  *value = subst_env_in_string(str, errmsg);
+  return *value != NULL;
 }
 
-char *
-confitem_format_env_string(const void *value)
+char*
+confitem_format_env_string(const voidvalue)
 {
-       return format_string(value);
+  return format_string(value);
 }
 
 bool
-confitem_parse_double(const char *str, void *result, char **errmsg)
+confitem_parse_double(const char* str, void* result, char** errmsg)
 {
-       double *value = (double *)result;
-       errno = 0;
-       char *endptr;
-       double x = strtod(str, &endptr);
-       if (errno == 0 && *str != '\0' && *endptr == '\0') {
-               *value = x;
-               return true;
-       } else {
-               *errmsg = format("invalid floating point: \"%s\"", str);
-               return false;
-       }
+  double* value = (double*)result;
+  errno = 0;
+  char* endptr;
+  double x = strtod(str, &endptr);
+  if (errno == 0 && *str != '\0' && *endptr == '\0') {
+    *value = x;
+    return true;
+  } else {
+    *errmsg = format("invalid floating point: \"%s\"", str);
+    return false;
+  }
 }
 
-char *
-confitem_format_double(const void *value)
+char*
+confitem_format_double(const voidvalue)
 {
-       const double *x = (const double *)value;
-       return format("%.1f", *x);
+  const double* x = (const double*)value;
+  return format("%.1f", *x);
 }
 
 bool
-confitem_parse_size(const char *str, void *result, char **errmsg)
+confitem_parse_size(const char* str, void* result, char** errmsg)
 {
-       uint64_t *value = (uint64_t *)result;
-       uint64_t size;
-       if (parse_size_with_suffix(str, &size)) {
-               *value = size;
-               return true;
-       } else {
-               *errmsg = format("invalid size: \"%s\"", str);
-               return false;
-       }
+  uint64_t* value = (uint64_t*)result;
+  uint64_t size;
+  if (parse_size_with_suffix(str, &size)) {
+    *value = size;
+    return true;
+  } else {
+    *errmsg = format("invalid size: \"%s\"", str);
+    return false;
+  }
 }
 
-char *
-confitem_format_size(const void *value)
+char*
+confitem_format_size(const voidvalue)
 {
-       const uint64_t *size = (const uint64_t *)value;
-       return format_parsable_size_with_suffix(*size);
+  const uint64_t* size = (const uint64_t*)value;
+  return format_parsable_size_with_suffix(*size);
 }
 
 bool
-confitem_parse_sloppiness(const char *str, void *result, char **errmsg)
+confitem_parse_sloppiness(const char* str, void* result, char** errmsg)
 {
-       unsigned *value = (unsigned *)result;
-       if (!str) {
-               return *value;
-       }
+  unsigned* value = (unsigned*)result;
+  if (!str) {
+    return *value;
+  }
 
-       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;
-               } else if (str_eq(word, "file_stat_matches")) {
-                       *value |= SLOPPY_FILE_STAT_MATCHES;
-               } else if (str_eq(word, "file_stat_matches_ctime")) {
-                       *value |= SLOPPY_FILE_STAT_MATCHES_CTIME;
-               } else if (str_eq(word, "include_file_ctime")) {
-                       *value |= SLOPPY_INCLUDE_FILE_CTIME;
-               } else if (str_eq(word, "include_file_mtime")) {
-                       *value |= SLOPPY_INCLUDE_FILE_MTIME;
-               } else if (str_eq(word, "system_headers")
-                          || str_eq(word, "no_system_headers")) {
-                       *value |= SLOPPY_SYSTEM_HEADERS;
-               } else if (str_eq(word, "pch_defines")) {
-                       *value |= SLOPPY_PCH_DEFINES;
-               } else if (str_eq(word, "time_macros")) {
-                       *value |= SLOPPY_TIME_MACROS;
-               } else if (str_eq(word, "clang_index_store")) {
-                       *value |= SLOPPY_CLANG_INDEX_STORE;
-               } else if (str_eq(word, "locale")) {
-                       *value |= SLOPPY_LOCALE;
-               } else {
-                       *errmsg = format("unknown sloppiness: \"%s\"", word);
-                       free(p);
-                       return false;
-               }
-               q = NULL;
-       }
-       free(p);
-       return true;
+  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;
+    } else if (str_eq(word, "file_stat_matches")) {
+      *value |= SLOPPY_FILE_STAT_MATCHES;
+    } else if (str_eq(word, "file_stat_matches_ctime")) {
+      *value |= SLOPPY_FILE_STAT_MATCHES_CTIME;
+    } else if (str_eq(word, "include_file_ctime")) {
+      *value |= SLOPPY_INCLUDE_FILE_CTIME;
+    } else if (str_eq(word, "include_file_mtime")) {
+      *value |= SLOPPY_INCLUDE_FILE_MTIME;
+    } else if (str_eq(word, "system_headers")
+               || str_eq(word, "no_system_headers")) {
+      *value |= SLOPPY_SYSTEM_HEADERS;
+    } else if (str_eq(word, "pch_defines")) {
+      *value |= SLOPPY_PCH_DEFINES;
+    } else if (str_eq(word, "time_macros")) {
+      *value |= SLOPPY_TIME_MACROS;
+    } else if (str_eq(word, "clang_index_store")) {
+      *value |= SLOPPY_CLANG_INDEX_STORE;
+    } else if (str_eq(word, "locale")) {
+      *value |= SLOPPY_LOCALE;
+    } else {
+      *errmsg = format("unknown sloppiness: \"%s\"", word);
+      free(p);
+      return false;
+    }
+    q = NULL;
+  }
+  free(p);
+  return true;
 }
 
-char *
-confitem_format_sloppiness(const void *value)
+char*
+confitem_format_sloppiness(const voidvalue)
 {
-       const unsigned *sloppiness = (const unsigned *)value;
-       char *s = x_strdup("");
-       if (*sloppiness & SLOPPY_FILE_MACRO) {
-               reformat(&s, "%sfile_macro, ", s);
-       }
-       if (*sloppiness & SLOPPY_INCLUDE_FILE_MTIME) {
-               reformat(&s, "%sinclude_file_mtime, ", s);
-       }
-       if (*sloppiness & SLOPPY_INCLUDE_FILE_CTIME) {
-               reformat(&s, "%sinclude_file_ctime, ", s);
-       }
-       if (*sloppiness & SLOPPY_TIME_MACROS) {
-               reformat(&s, "%stime_macros, ", s);
-       }
-       if (*sloppiness & SLOPPY_PCH_DEFINES) {
-               reformat(&s, "%spch_defines, ", s);
-       }
-       if (*sloppiness & SLOPPY_FILE_STAT_MATCHES) {
-               reformat(&s, "%sfile_stat_matches, ", s);
-       }
-       if (*sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME) {
-               reformat(&s, "%sfile_stat_matches_ctime, ", s);
-       }
-       if (*sloppiness & SLOPPY_SYSTEM_HEADERS) {
-               reformat(&s, "%ssystem_headers, ", s);
-       }
-       if (*sloppiness & SLOPPY_CLANG_INDEX_STORE) {
-               reformat(&s, "%sclang_index_store, ", s);
-       }
-       if (*sloppiness & SLOPPY_LOCALE) {
-               reformat(&s, "%slocale, ", s);
-       }
-       if (*sloppiness) {
-               // Strip last ", ".
-               s[strlen(s) - 2] = '\0';
-       }
-       return s;
+  const unsigned* sloppiness = (const unsigned*)value;
+  char* s = x_strdup("");
+  if (*sloppiness & SLOPPY_FILE_MACRO) {
+    reformat(&s, "%sfile_macro, ", s);
+  }
+  if (*sloppiness & SLOPPY_INCLUDE_FILE_MTIME) {
+    reformat(&s, "%sinclude_file_mtime, ", s);
+  }
+  if (*sloppiness & SLOPPY_INCLUDE_FILE_CTIME) {
+    reformat(&s, "%sinclude_file_ctime, ", s);
+  }
+  if (*sloppiness & SLOPPY_TIME_MACROS) {
+    reformat(&s, "%stime_macros, ", s);
+  }
+  if (*sloppiness & SLOPPY_PCH_DEFINES) {
+    reformat(&s, "%spch_defines, ", s);
+  }
+  if (*sloppiness & SLOPPY_FILE_STAT_MATCHES) {
+    reformat(&s, "%sfile_stat_matches, ", s);
+  }
+  if (*sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME) {
+    reformat(&s, "%sfile_stat_matches_ctime, ", s);
+  }
+  if (*sloppiness & SLOPPY_SYSTEM_HEADERS) {
+    reformat(&s, "%ssystem_headers, ", s);
+  }
+  if (*sloppiness & SLOPPY_CLANG_INDEX_STORE) {
+    reformat(&s, "%sclang_index_store, ", s);
+  }
+  if (*sloppiness & SLOPPY_LOCALE) {
+    reformat(&s, "%slocale, ", s);
+  }
+  if (*sloppiness) {
+    // Strip last ", ".
+    s[strlen(s) - 2] = '\0';
+  }
+  return s;
 }
 
 bool
-confitem_parse_string(const char *str, void *result, char **errmsg)
+confitem_parse_string(const char* str, void* result, char** errmsg)
 {
-       (void)errmsg;
+  (void)errmsg;
 
-       char **value = (char **)result;
-       free(*value);
-       *value = x_strdup(str);
-       return true;
+  char** value = (char**)result;
+  free(*value);
+  *value = x_strdup(str);
+  return true;
 }
 
-char *
-confitem_format_string(const void *value)
+char*
+confitem_format_string(const voidvalue)
 {
-       return format_string(value);
+  return format_string(value);
 }
 
 bool
-confitem_parse_umask(const char *str, void *result, char **errmsg)
+confitem_parse_umask(const char* str, void* result, char** errmsg)
 {
-       unsigned *value = (unsigned *)result;
-       if (str_eq(str, "")) {
-               *value = UINT_MAX;
-               return true;
-       }
+  unsigned* value = (unsigned*)result;
+  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;
-       } else {
-               *errmsg = format("not an octal integer: \"%s\"", str);
-               return false;
-       }
+  errno = 0;
+  char* endptr;
+  *value = strtoul(str, &endptr, 8);
+  if (errno == 0 && *str != '\0' && *endptr == '\0') {
+    return true;
+  } else {
+    *errmsg = format("not an octal integer: \"%s\"", str);
+    return false;
+  }
 }
 
-char *
-confitem_format_umask(const void *value)
+char*
+confitem_format_umask(const voidvalue)
 {
-       const unsigned *umask = (const unsigned *)value;
-       if (*umask == UINT_MAX) {
-               return x_strdup("");
-       } else {
-               return format("%03o", *umask);
-       }
+  const unsigned* umask = (const unsigned*)value;
+  if (*umask == UINT_MAX) {
+    return x_strdup("");
+  } else {
+    return format("%03o", *umask);
+  }
 }
 
 bool
-confitem_parse_int(const char *str, void *result, char **errmsg)
+confitem_parse_int(const char* str, void* result, char** errmsg)
 {
-       int *value = (int *)result;
-       errno = 0;
-       char *endptr;
-       long x = strtol(str, &endptr, 10);
-       if (errno == 0 && *str != '\0' && *endptr == '\0') {
-               *value = x;
-               return true;
-       } else {
-               *errmsg = format("invalid integer: \"%s\"", str);
-               return false;
-       }
+  int* value = (int*)result;
+  errno = 0;
+  char* endptr;
+  long x = strtol(str, &endptr, 10);
+  if (errno == 0 && *str != '\0' && *endptr == '\0') {
+    *value = x;
+    return true;
+  } else {
+    *errmsg = format("invalid integer: \"%s\"", str);
+    return false;
+  }
 }
 
-char *
-confitem_format_int(const void *value)
+char*
+confitem_format_int(const voidvalue)
 {
-       const int *i = (const int *)value;
-       return format("%d", *i);
+  const int* i = (const int*)value;
+  return format("%d", *i);
 }
 
 bool
-confitem_parse_unsigned(const char *str, void *result, char **errmsg)
+confitem_parse_unsigned(const char* str, void* result, char** errmsg)
 {
-       unsigned *value = (unsigned *)result;
-       errno = 0;
-       char *endptr;
-       long x = strtol(str, &endptr, 10);
-       if (errno == 0 && x >= 0 && *str != '\0' && *endptr == '\0') {
-               *value = x;
-               return true;
-       } else {
-               *errmsg = format("invalid unsigned integer: \"%s\"", str);
-               return false;
-       }
+  unsigned* value = (unsigned*)result;
+  errno = 0;
+  char* endptr;
+  long x = strtol(str, &endptr, 10);
+  if (errno == 0 && x >= 0 && *str != '\0' && *endptr == '\0') {
+    *value = x;
+    return true;
+  } else {
+    *errmsg = format("invalid unsigned integer: \"%s\"", str);
+    return false;
+  }
 }
 
-char *
-confitem_format_unsigned(const void *value)
+char*
+confitem_format_unsigned(const voidvalue)
 {
-       const unsigned *i = (const unsigned *)value;
-       return format("%u", *i);
+  const unsigned* i = (const unsigned*)value;
+  return format("%u", *i);
 }
 
 bool
-confitem_verify_absolute_path(const void *value, char **errmsg)
+confitem_verify_absolute_path(const void* value, char** errmsg)
 {
-       const char *const *path = (const char *const *)value;
-       assert(*path);
-       if (str_eq(*path, "")) {
-               // The empty string means "disable" in this case.
-               return true;
-       } else if (is_absolute_path(*path)) {
-               return true;
-       } else {
-               *errmsg = format("not an absolute path: \"%s\"", *path);
-               return false;
-       }
+  const char* const* path = (const char* const*)value;
+  assert(*path);
+  if (str_eq(*path, "")) {
+    // The empty string means "disable" in this case.
+    return true;
+  } else if (is_absolute_path(*path)) {
+    return true;
+  } else {
+    *errmsg = format("not an absolute path: \"%s\"", *path);
+    return false;
+  }
 }
 
 bool
-confitem_verify_compression_level(const void *value, char **errmsg)
+confitem_verify_compression_level(const void* value, char** errmsg)
 {
-       const int *level = (const int *)value;
-       assert(level);
-       if (*level >= -128 && *level <= 127) {
-               return true;
-       } else {
-               *errmsg = format("compression level must be between -128 and 127");
-               return false;
-       }
+  const int* level = (const int*)value;
+  assert(level);
+  if (*level >= -128 && *level <= 127) {
+    return true;
+  } else {
+    *errmsg = format("compression level must be between -128 and 127");
+    return false;
+  }
 }
 
 bool
-confitem_verify_dir_levels(const void *value, char **errmsg)
+confitem_verify_dir_levels(const void* value, char** errmsg)
 {
-       const unsigned *levels = (const unsigned *)value;
-       assert(levels);
-       if (*levels >= 1 && *levels <= 8) {
-               return true;
-       } else {
-               *errmsg = format("cache directory levels must be between 1 and 8");
-               return false;
-       }
+  const unsigned* levels = (const unsigned*)value;
+  assert(levels);
+  if (*levels >= 1 && *levels <= 8) {
+    return true;
+  } else {
+    *errmsg = format("cache directory levels must be between 1 and 8");
+    return false;
+  }
 }
index ae2f25344320d109e5a3022848b92d1dd318598e..aba12d9835ebf5d7f26d12ddff9cb492d7ac173f 100644 (file)
 
 #include "system.hpp"
 
-typedef bool (*conf_item_parser)(const char *str, void *result, char **errmsg);
-typedef bool (*conf_item_verifier)(const void *value, char **errmsg);
-typedef char *(*conf_item_formatter)(const void *value);
+typedef bool (*conf_item_parser)(const char* str, void* result, char** errmsg);
+typedef bool (*conf_item_verifier)(const void* value, char** errmsg);
+typedef char* (*conf_item_formatter)(const void* value);
 
-struct conf_item {
-       const char *name;
-       size_t number;
-       size_t offset;
-       conf_item_parser parser;
-       conf_item_formatter formatter;
-       conf_item_verifier verifier;
+struct conf_item
+{
+  const char* name;
+  size_t number;
+  size_t offset;
+  conf_item_parser parser;
+  conf_item_formatter formatter;
+  conf_item_verifier verifier;
 };
 
-bool confitem_parse_bool(const char *str, void *result, char **errmsg);
-char *confitem_format_bool(const void *value);
+bool confitem_parse_bool(const char* str, void* result, char** errmsg);
+char* confitem_format_bool(const void* value);
 
-bool confitem_parse_env_string(const char *str, void *result, char **errmsg);
-char *confitem_format_env_string(const void *value);
+bool confitem_parse_env_string(const char* str, void* result, char** errmsg);
+char* confitem_format_env_string(const void* value);
 
-bool confitem_parse_double(const char *str, void *result, char **errmsg);
-char *confitem_format_double(const void *value);
+bool confitem_parse_double(const char* str, void* result, char** errmsg);
+char* confitem_format_double(const void* value);
 
-bool confitem_parse_size(const char *str, void *result, char **errmsg);
-char *confitem_format_size(const void *value);
+bool confitem_parse_size(const char* str, void* result, char** errmsg);
+char* confitem_format_size(const void* value);
 
-bool confitem_parse_sloppiness(const char *str, void *result, char **errmsg);
-char *confitem_format_sloppiness(const void *value);
+bool confitem_parse_sloppiness(const char* str, void* result, char** errmsg);
+char* confitem_format_sloppiness(const void* value);
 
-bool confitem_parse_string(const char *str, void *result, char **errmsg);
-char *confitem_format_string(const void *value);
+bool confitem_parse_string(const char* str, void* result, char** errmsg);
+char* confitem_format_string(const void* value);
 
-bool confitem_parse_umask(const char *str, void *result, char **errmsg);
-char *confitem_format_umask(const void *value);
+bool confitem_parse_umask(const char* str, void* result, char** errmsg);
+char* confitem_format_umask(const void* value);
 
-bool confitem_parse_int(const char *str, void *result, char **errmsg);
-char *confitem_format_int(const void *value);
+bool confitem_parse_int(const char* str, void* result, char** errmsg);
+char* confitem_format_int(const void* value);
 
-bool confitem_parse_unsigned(const char *str, void *result, char **errmsg);
-char *confitem_format_unsigned(const void *value);
+bool confitem_parse_unsigned(const char* str, void* result, char** errmsg);
+char* confitem_format_unsigned(const void* value);
 
-bool confitem_verify_absolute_path(const void *value, char **errmsg);
-bool confitem_verify_compression_level(const void *value, char **errmsg);
-bool confitem_verify_dir_levels(const void *value, char **errmsg);
+bool confitem_verify_absolute_path(const void* value, char** errmsg);
+bool confitem_verify_compression_level(const void* value, char** errmsg);
+bool confitem_verify_dir_levels(const void* value, char** errmsg);
 
-const struct conf_item *confitems_get(const char *str, size_t len);
+const struct conf_item* confitems_get(const char* str, size_t len);
 size_t confitems_count(void);
index d846f9d83776dfba04719d6dc0b3bd8e3bbd7fb2..ade493c26513622c32a7c1bd8fe735c2b427d252 100644 (file)
 
 // Allocate and initialize a struct counters. Data entries up to the size are
 // set to 0.
-struct counters *
+struct counters*
 counters_init(size_t initial_size)
 {
-       auto c = static_cast<counters*>(x_malloc(sizeof(counters)));
-       c->data = NULL;
-       c->size = 0;
-       c->allocated = 0;
-       counters_resize(c, initial_size);
-       return c;
+  auto c = static_cast<counters*>(x_malloc(sizeof(counters)));
+  c->data = NULL;
+  c->size = 0;
+  c->allocated = 0;
+  counters_resize(c, initial_size);
+  return c;
 }
 
 // Free a counters struct.
 void
-counters_free(struct counters *c)
+counters_free(struct countersc)
 {
-       if (c) {
-               free(c->data);
-               free(c);
-       }
+  if (c) {
+    free(c->data);
+    free(c);
+  }
 }
 
 // Set a new size. New data entries are set to 0.
 void
-counters_resize(struct counters *c, size_t new_size)
+counters_resize(struct countersc, size_t new_size)
 {
-       if (new_size > c->size) {
-               bool realloc = false;
-               while (c->allocated < new_size) {
-                       c->allocated += 32 + c->allocated;
-                       realloc = true;
-               }
-               if (realloc) {
-                       c->data = static_cast<unsigned*>(
-                               x_realloc(c->data, c->allocated * sizeof(c->data[0])));
-               }
-               for (size_t i = c->size; i < new_size; i++) {
-                       c->data[i] = 0;
-               }
-       }
+  if (new_size > c->size) {
+    bool realloc = false;
+    while (c->allocated < new_size) {
+      c->allocated += 32 + c->allocated;
+      realloc = true;
+    }
+    if (realloc) {
+      c->data = static_cast<unsigned*>(
+        x_realloc(c->data, c->allocated * sizeof(c->data[0])));
+    }
+    for (size_t i = c->size; i < new_size; i++) {
+      c->data[i] = 0;
+    }
+  }
 
-       c->size = new_size;
+  c->size = new_size;
 }
index 43d334b607da565b5856535e5cd9af5a47739a37..c2560b73ed4b4525fd1feec00f3c69b51a4aab40 100644 (file)
 
 #include <stddef.h>
 
-struct counters {
-       unsigned *data;   // counter value
-       size_t size;      // logical array size
-       size_t allocated; // allocated size
+struct counters
+{
+  unsigned* data;   // counter value
+  size_t size;      // logical array size
+  size_t allocated; // allocated size
 };
 
-struct counters *counters_init(size_t initial_size);
-void counters_resize(struct counters *c, size_t new_size);
-void counters_free(struct counters *c);
+struct counterscounters_init(size_t initial_size);
+void counters_resize(struct countersc, size_t new_size);
+void counters_free(struct countersc);
index e4c87c7e0d9ea295fedef345933b558339753051..4c40cd49b3cc97499bbb85db7b7463879abf606a 100644 (file)
 
 #include "compression.hpp"
 
-struct state {
-       FILE *input;
-       XXH64_state_t *checksum;
-       bool failed;
+struct state
+{
+  FILE* input;
+  XXH64_state_t* checksum;
+  bool failed;
 };
 
-static struct decompr_state *
-decompr_none_init(FILE *input, XXH64_state_t *checksum)
+static struct decompr_state*
+decompr_none_init(FILE* input, XXH64_state_t* checksum)
 {
-       auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
-       state->input = input;
-       state->checksum = checksum;
-       state->failed = false;
-       return (struct decompr_state *)state;
+  auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
+  state->input = input;
+  state->checksum = checksum;
+  state->failed = false;
+  return (struct decompr_state*)state;
 }
 
 static bool
-decompr_none_read(struct decompr_state *handle, void *data, size_t size)
+decompr_none_read(struct decompr_state* handle, void* data, size_t size)
 {
-       struct state *state = (struct state *)handle;
+  struct state* state = (struct state*)handle;
 
-       bool result = fread(data, 1, size, state->input) == size;
-       if (result && state->checksum) {
-               XXH64_update(state->checksum, data, size);
-       }
-       if (!result) {
-               state->failed = true;
-       }
-       return result;
+  bool result = fread(data, 1, size, state->input) == size;
+  if (result && state->checksum) {
+    XXH64_update(state->checksum, data, size);
+  }
+  if (!result) {
+    state->failed = true;
+  }
+  return result;
 }
 
 static bool
-decompr_none_free(struct decompr_state *handle)
+decompr_none_free(struct decompr_statehandle)
 {
-       struct state *state = (struct state *)handle;
-       bool result = !state->failed;
-       free(state);
-       return result;
+  struct state* state = (struct state*)handle;
+  bool result = !state->failed;
+  free(state);
+  return result;
 }
 
 struct decompressor decompressor_none_impl = {
-       decompr_none_init,
-       decompr_none_read,
-       decompr_none_free
-};
+  decompr_none_init, decompr_none_read, decompr_none_free};
index b6691654e738f17da861d3d43374ec824a397d95..9fb895c311e08d5e4c06776d8c068c1b9f093338 100644 (file)
 #include <zstd.h>
 
 enum stream_state {
-       STREAM_STATE_READING,
-       STREAM_STATE_FAILED,
-       STREAM_STATE_END
+  STREAM_STATE_READING,
+  STREAM_STATE_FAILED,
+  STREAM_STATE_END
 };
 
-struct state {
-       FILE *input;
-       XXH64_state_t *checksum;
-       char input_buffer[READ_BUFFER_SIZE];
-       size_t input_size;
-       size_t input_consumed;
-       ZSTD_DStream *stream;
-       ZSTD_inBuffer in;
-       ZSTD_outBuffer out;
-       enum stream_state stream_state;
+struct state
+{
+  FILE* input;
+  XXH64_state_t* checksum;
+  char input_buffer[READ_BUFFER_SIZE];
+  size_t input_size;
+  size_t input_consumed;
+  ZSTD_DStream* stream;
+  ZSTD_inBuffer in;
+  ZSTD_outBuffer out;
+  enum stream_state stream_state;
 };
 
-static struct decompr_state *
-decompr_zstd_init(FILE *input, XXH64_state_t *checksum)
+static struct decompr_state*
+decompr_zstd_init(FILE* input, XXH64_state_t* checksum)
 {
-       auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
+  auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
 
-       state->input = input;
-       state->checksum = checksum;
-       state->input_size = 0;
-       state->input_consumed = 0;
-       state->stream = ZSTD_createDStream();
-       state->stream_state = STREAM_STATE_READING;
+  state->input = input;
+  state->checksum = checksum;
+  state->input_size = 0;
+  state->input_consumed = 0;
+  state->stream = ZSTD_createDStream();
+  state->stream_state = STREAM_STATE_READING;
 
-       size_t ret = ZSTD_initDStream(state->stream);
-       if (ZSTD_isError(ret)) {
-               ZSTD_freeDStream(state->stream);
-               free(state);
-               return NULL;
-       }
-       return (struct decompr_state *)state;
+  size_t ret = ZSTD_initDStream(state->stream);
+  if (ZSTD_isError(ret)) {
+    ZSTD_freeDStream(state->stream);
+    free(state);
+    return NULL;
+  }
+  return (struct decompr_state*)state;
 }
 
 static bool
-decompr_zstd_read(struct decompr_state *handle, void *data, size_t size)
+decompr_zstd_read(struct decompr_state* handle, void* data, size_t size)
 {
-       if (!handle) {
-               return false;
-       }
-       struct state *state = (struct state *)handle;
+  if (!handle) {
+    return false;
+  }
+  struct state* state = (struct state*)handle;
 
-       size_t bytes_read = 0;
-       while (bytes_read < size) {
-               assert(state->input_size >= state->input_consumed);
-               if (state->input_size == state->input_consumed) {
-                       state->input_size = fread(
-                               state->input_buffer, 1, sizeof(state->input_buffer), state->input);
-                       if (state->input_size == 0) {
-                               state->stream_state = STREAM_STATE_FAILED;
-                               return false;
-                       }
-                       state->input_consumed = 0;
-               }
+  size_t bytes_read = 0;
+  while (bytes_read < size) {
+    assert(state->input_size >= state->input_consumed);
+    if (state->input_size == state->input_consumed) {
+      state->input_size = fread(
+        state->input_buffer, 1, sizeof(state->input_buffer), state->input);
+      if (state->input_size == 0) {
+        state->stream_state = STREAM_STATE_FAILED;
+        return false;
+      }
+      state->input_consumed = 0;
+    }
 
-               state->in.src = (state->input_buffer + state->input_consumed);
-               state->in.size = state->input_size - state->input_consumed;
-               state->in.pos = 0;
+    state->in.src = (state->input_buffer + state->input_consumed);
+    state->in.size = state->input_size - state->input_consumed;
+    state->in.pos = 0;
 
-               state->out.dst = ((char *)data + bytes_read);
-               state->out.size = size - bytes_read;
-               state->out.pos = 0;
-               size_t ret = ZSTD_decompressStream(state->stream, &state->out, &state->in);
-               if (ZSTD_isError(ret)) {
-                       state->stream_state = STREAM_STATE_FAILED;
-                       return false;
-               }
-               if (state->checksum) {
-                       XXH64_update(state->checksum, state->out.dst, state->out.pos);
-               }
-               if (ret == 0) {
-                       state->stream_state = STREAM_STATE_END;
-                       break;
-               }
-               bytes_read += state->out.pos;
-               state->input_consumed += state->in.pos;
-       }
+    state->out.dst = ((char*)data + bytes_read);
+    state->out.size = size - bytes_read;
+    state->out.pos = 0;
+    size_t ret = ZSTD_decompressStream(state->stream, &state->out, &state->in);
+    if (ZSTD_isError(ret)) {
+      state->stream_state = STREAM_STATE_FAILED;
+      return false;
+    }
+    if (state->checksum) {
+      XXH64_update(state->checksum, state->out.dst, state->out.pos);
+    }
+    if (ret == 0) {
+      state->stream_state = STREAM_STATE_END;
+      break;
+    }
+    bytes_read += state->out.pos;
+    state->input_consumed += state->in.pos;
+  }
 
-       return true;
+  return true;
 }
 
-static bool decompr_zstd_free(struct decompr_state *handle)
+static bool
+decompr_zstd_free(struct decompr_state* handle)
 {
-       if (!handle) {
-               return false;
-       }
-       struct state *state = (struct state *)handle;
-       ZSTD_freeDStream(state->stream);
-       bool success = state->stream_state == STREAM_STATE_END;
-       free(handle);
-       return success;
+  if (!handle) {
+    return false;
+  }
+  struct state* state = (struct state*)handle;
+  ZSTD_freeDStream(state->stream);
+  bool success = state->stream_state == STREAM_STATE_END;
+  free(handle);
+  return success;
 }
 
 struct decompressor decompressor_zstd_impl = {
-       decompr_zstd_init,
-       decompr_zstd_read,
-       decompr_zstd_free
-};
+  decompr_zstd_init, decompr_zstd_read, decompr_zstd_free};
index 425e38f808d4a8b3a1009824cdee8fa06e1c1788..7885b483a6019f83688362f9bb99b62e8a2a15b3 100644 (file)
 
 #include "system.hpp"
 
-struct env_to_conf_item {
-       const char *env_name;
-       const char *conf_name;
+struct env_to_conf_item
+{
+  const char* env_name;
+  const char* conf_name;
 };
 
-const struct env_to_conf_item *envtoconfitems_get(const char *str, size_t len);
+const struct env_to_conf_item* envtoconfitems_get(const char* str, size_t len);
 
 size_t envtoconfitems_count(void);
index 2a31bfae7e20a2a81c4c50bc6dca61e1105909fc..fb5c638ff70665b1de1e9badac15cc14b8b10183 100644 (file)
 
 #include "ccache.hpp"
 
-extern struct conf *conf;
+extern struct confconf;
 
-static char *
-find_executable_in_path(const char *name, const char *exclude_name, char *path);
+static char*
+find_executable_in_path(const char* name, const char* exclude_name, char* path);
 
 #ifdef _WIN32
 // Re-create a win32 command line string based on **argv.
 // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
-char *
-win32argvtos(char *prefix, char **argv, int *length)
+char*
+win32argvtos(char* prefix, char** argv, int* length)
 {
-       int i = 0;
-       int k = 0;
-       char *arg = prefix ? prefix : argv[i++];
-       do {
-               int bs = 0;
-               for (int j = 0; arg[j]; j++) {
-                       switch (arg[j]) {
-                       case '\\':
-                               bs++;
-                               break;
-                       case '"':
-                               bs = (bs << 1) + 1;
-                       // Fallthrough.
-                       default:
-                               k += bs + 1;
-                               bs = 0;
-                       }
-               }
-               k += (bs << 1) + 3;
-       } while ((arg = argv[i++]));
-
-       char *ptr = static_cast<char*>(malloc(k + 1));
-       char *str = ptr;
-       if (!str) {
-               *length = 0;
-               return NULL;
-       }
-
-       i = 0;
-       arg = prefix ? prefix : argv[i++];
-       do {
-               int bs = 0;
-               *ptr++ = '"';
-               for (int j = 0; arg[j]; j++) {
-                       switch (arg[j]) {
-                       case '\\':
-                               bs++;
-                               break;
-                       // Fallthrough.
-                       case '"':
-                               bs = (bs << 1) + 1;
-                       // Fallthrough.
-                       default:
-                               while (bs && bs--) {
-                                       *ptr++ = '\\';
-                               }
-                               *ptr++ = arg[j];
-                       }
-               }
-               bs <<= 1;
-               while (bs && bs--) {
-                       *ptr++ = '\\';
-               }
-               *ptr++ = '"';
-               *ptr++ = ' ';
-       } while ((arg = argv[i++]));
-       ptr[-1] = '\0';
-
-       *length = ptr - str - 1;
-       return str;
+  int i = 0;
+  int k = 0;
+  char* arg = prefix ? prefix : argv[i++];
+  do {
+    int bs = 0;
+    for (int j = 0; arg[j]; j++) {
+      switch (arg[j]) {
+      case '\\':
+        bs++;
+        break;
+      case '"':
+        bs = (bs << 1) + 1;
+      // Fallthrough.
+      default:
+        k += bs + 1;
+        bs = 0;
+      }
+    }
+    k += (bs << 1) + 3;
+  } while ((arg = argv[i++]));
+
+  char* ptr = static_cast<char*>(malloc(k + 1));
+  char* str = ptr;
+  if (!str) {
+    *length = 0;
+    return NULL;
+  }
+
+  i = 0;
+  arg = prefix ? prefix : argv[i++];
+  do {
+    int bs = 0;
+    *ptr++ = '"';
+    for (int j = 0; arg[j]; j++) {
+      switch (arg[j]) {
+      case '\\':
+        bs++;
+        break;
+      // Fallthrough.
+      case '"':
+        bs = (bs << 1) + 1;
+      // Fallthrough.
+      default:
+        while (bs && bs--) {
+          *ptr++ = '\\';
+        }
+        *ptr++ = arg[j];
+      }
+    }
+    bs <<= 1;
+    while (bs && bs--) {
+      *ptr++ = '\\';
+    }
+    *ptr++ = '"';
+    *ptr++ = ' ';
+  } while ((arg = argv[i++]));
+  ptr[-1] = '\0';
+
+  *length = ptr - str - 1;
+  return str;
 }
 
-char *
-win32getshell(char *path)
+char*
+win32getshell(charpath)
 {
-       char *path_env;
-       char *sh = NULL;
-       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 = fopen(path, "r");
-               if (fp) {
-                       char buf[10];
-                       fgets(buf, sizeof(buf), fp);
-                       buf[9] = 0;
-                       if (str_eq(buf, "#!/bin/sh") && (path_env = getenv("PATH"))) {
-                               sh = find_executable_in_path("sh.exe", NULL, path_env);
-                       }
-                       fclose(fp);
-               }
-       }
-
-       return sh;
+  char* path_env;
+  char* sh = NULL;
+  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 = fopen(path, "r");
+    if (fp) {
+      char buf[10];
+      fgets(buf, sizeof(buf), fp);
+      buf[9] = 0;
+      if (str_eq(buf, "#!/bin/sh") && (path_env = getenv("PATH"))) {
+        sh = find_executable_in_path("sh.exe", NULL, path_env);
+      }
+      fclose(fp);
+    }
+  }
+
+  return sh;
 }
 
-void add_exe_ext_if_no_to_fullpath(char *full_path_win_ext, size_t max_size,
-                                   const char *ext, const char *path) {
-       if (!ext || (!str_eq(".exe", ext)
-                    && !str_eq(".sh", ext)
-                    && !str_eq(".bat", ext)
-                    && !str_eq(".EXE", ext)
-                    && !str_eq(".BAT", ext))) {
-               snprintf(full_path_win_ext, max_size, "%s.exe", path);
-       } else {
-               snprintf(full_path_win_ext, max_size, "%s", path);
-       }
+void
+add_exe_ext_if_no_to_fullpath(char* full_path_win_ext,
+                              size_t max_size,
+                              const char* ext,
+                              const char* path)
+{
+  if (!ext
+      || (!str_eq(".exe", ext) && !str_eq(".sh", ext) && !str_eq(".bat", ext)
+          && !str_eq(".EXE", ext) && !str_eq(".BAT", ext))) {
+    snprintf(full_path_win_ext, max_size, "%s.exe", path);
+  } else {
+    snprintf(full_path_win_ext, max_size, "%s", path);
+  }
 }
 
 int
-win32execute(char *path, char **argv, int doreturn,
-             int fd_stdout, int fd_stderr)
+win32execute(
+  char* path, char** argv, int doreturn, int fd_stdout, int fd_stderr)
 {
-       PROCESS_INFORMATION pi;
-       memset(&pi, 0x00, sizeof(pi));
-
-       STARTUPINFO si;
-       memset(&si, 0x00, sizeof(si));
-
-       char *sh = win32getshell(path);
-       if (sh) {
-               path = sh;
-       }
-
-       si.cb = sizeof(STARTUPINFO);
-       if (fd_stdout != -1) {
-               si.hStdOutput = (HANDLE)_get_osfhandle(fd_stdout);
-               si.hStdError = (HANDLE)_get_osfhandle(fd_stderr);
-               si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
-               si.dwFlags = STARTF_USESTDHANDLES;
-               if (si.hStdOutput == INVALID_HANDLE_VALUE
-                   || si.hStdError == INVALID_HANDLE_VALUE) {
-                       return -1;
-               }
-       } else {
-               // Redirect subprocess stdout, stderr into current process.
-               si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
-               si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-               si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
-               si.dwFlags = STARTF_USESTDHANDLES;
-               if (si.hStdOutput == INVALID_HANDLE_VALUE
-                   || si.hStdError == INVALID_HANDLE_VALUE) {
-                       return -1;
-               }
-       }
-
-       int length;
-       char *args = win32argvtos(sh, argv, &length);
-       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);
-       BOOL ret = FALSE;
-       if (length > 8192) {
-               char *tmp_file = format("%s.tmp", path);
-               FILE *fp = create_tmp_file(&tmp_file, "w");
-               char atfile[MAX_PATH + 3];
-               fwrite(args, 1, length, fp);
-               if (ferror(fp)) {
-                       cc_log("Error writing @file; this command will probably fail: %s", args);
-               }
-               fclose(fp);
-               snprintf(atfile, sizeof(atfile), "\"@%s\"", tmp_file);
-               ret = CreateProcess(NULL, atfile, NULL, NULL, 1, 0, NULL, NULL,
-                                   &si, &pi);
-               tmp_unlink(tmp_file);
-               free(tmp_file);
-       }
-       if (!ret) {
-               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;
-               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);
-
-               LPVOID lpDisplayBuf =
-                       (LPVOID) LocalAlloc(LMEM_ZEROINIT,
-                                           (lstrlen((LPCTSTR) lpMsgBuf)
-                                            + lstrlen((LPCTSTR) __FILE__) + 200)
-                                           * sizeof(TCHAR));
-               _snprintf((LPTSTR) lpDisplayBuf,
-                         LocalSize(lpDisplayBuf) / sizeof(TCHAR),
-                         TEXT("%s failed with error %lu: %s"), __FILE__, dw,
-                         (const char *)lpMsgBuf);
-
-               cc_log("can't execute %s; OS returned error: %s",
-                      full_path_win_ext, (char *)lpDisplayBuf);
-
-               LocalFree(lpMsgBuf);
-               LocalFree(lpDisplayBuf);
-
-               return -1;
-       }
-       WaitForSingleObject(pi.hProcess, INFINITE);
-
-       DWORD exitcode;
-       GetExitCodeProcess(pi.hProcess, &exitcode);
-       CloseHandle(pi.hProcess);
-       CloseHandle(pi.hThread);
-       if (!doreturn) {
-               x_exit(exitcode);
-       }
-       return exitcode;
+  PROCESS_INFORMATION pi;
+  memset(&pi, 0x00, sizeof(pi));
+
+  STARTUPINFO si;
+  memset(&si, 0x00, sizeof(si));
+
+  char* sh = win32getshell(path);
+  if (sh) {
+    path = sh;
+  }
+
+  si.cb = sizeof(STARTUPINFO);
+  if (fd_stdout != -1) {
+    si.hStdOutput = (HANDLE)_get_osfhandle(fd_stdout);
+    si.hStdError = (HANDLE)_get_osfhandle(fd_stderr);
+    si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+    si.dwFlags = STARTF_USESTDHANDLES;
+    if (si.hStdOutput == INVALID_HANDLE_VALUE
+        || si.hStdError == INVALID_HANDLE_VALUE) {
+      return -1;
+    }
+  } else {
+    // Redirect subprocess stdout, stderr into current process.
+    si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+    si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+    si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+    si.dwFlags = STARTF_USESTDHANDLES;
+    if (si.hStdOutput == INVALID_HANDLE_VALUE
+        || si.hStdError == INVALID_HANDLE_VALUE) {
+      return -1;
+    }
+  }
+
+  int length;
+  char* args = win32argvtos(sh, argv, &length);
+  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);
+  BOOL ret = FALSE;
+  if (length > 8192) {
+    char* tmp_file = format("%s.tmp", path);
+    FILE* fp = create_tmp_file(&tmp_file, "w");
+    char atfile[MAX_PATH + 3];
+    fwrite(args, 1, length, fp);
+    if (ferror(fp)) {
+      cc_log("Error writing @file; this command will probably fail: %s", args);
+    }
+    fclose(fp);
+    snprintf(atfile, sizeof(atfile), "\"@%s\"", tmp_file);
+    ret = CreateProcess(NULL, atfile, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
+    tmp_unlink(tmp_file);
+    free(tmp_file);
+  }
+  if (!ret) {
+    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;
+    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);
+
+    LPVOID lpDisplayBuf = (LPVOID)LocalAlloc(
+      LMEM_ZEROINIT,
+      (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)__FILE__) + 200)
+        * sizeof(TCHAR));
+    _snprintf((LPTSTR)lpDisplayBuf,
+              LocalSize(lpDisplayBuf) / sizeof(TCHAR),
+              TEXT("%s failed with error %lu: %s"),
+              __FILE__,
+              dw,
+              (const char*)lpMsgBuf);
+
+    cc_log("can't execute %s; OS returned error: %s",
+           full_path_win_ext,
+           (char*)lpDisplayBuf);
+
+    LocalFree(lpMsgBuf);
+    LocalFree(lpDisplayBuf);
+
+    return -1;
+  }
+  WaitForSingleObject(pi.hProcess, INFINITE);
+
+  DWORD exitcode;
+  GetExitCodeProcess(pi.hProcess, &exitcode);
+  CloseHandle(pi.hProcess);
+  CloseHandle(pi.hThread);
+  if (!doreturn) {
+    x_exit(exitcode);
+  }
+  return exitcode;
 }
 
 #else
@@ -243,156 +248,153 @@ win32execute(char *path, char **argv, int doreturn,
 // Execute a compiler backend, capturing all output to the given paths the full
 // path to the compiler to run is in argv[0].
 int
-execute(char **argv, int fd_out, int fd_err, pid_t *pid)
+execute(char** argv, int fd_out, int fd_err, pid_t* pid)
 {
-       cc_log_argv("Executing ", argv);
-
-       block_signals();
-       *pid = fork();
-       unblock_signals();
-
-       if (*pid == -1) {
-               fatal("Failed to fork: %s", strerror(errno));
-       }
-
-       if (*pid == 0) {
-               // Child.
-               dup2(fd_out, 1);
-               close(fd_out);
-               dup2(fd_err, 2);
-               close(fd_err);
-               x_exit(execv(argv[0], argv));
-       }
-
-       close(fd_out);
-       close(fd_err);
-
-       int status;
-       if (waitpid(*pid, &status, 0) != *pid) {
-               fatal("waitpid failed: %s", strerror(errno));
-       }
-
-       block_signals();
-       *pid = 0;
-       unblock_signals();
-
-       if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) {
-               return -1;
-       }
-
-       return WEXITSTATUS(status);
+  cc_log_argv("Executing ", argv);
+
+  block_signals();
+  *pid = fork();
+  unblock_signals();
+
+  if (*pid == -1) {
+    fatal("Failed to fork: %s", strerror(errno));
+  }
+
+  if (*pid == 0) {
+    // Child.
+    dup2(fd_out, 1);
+    close(fd_out);
+    dup2(fd_err, 2);
+    close(fd_err);
+    x_exit(execv(argv[0], argv));
+  }
+
+  close(fd_out);
+  close(fd_err);
+
+  int status;
+  if (waitpid(*pid, &status, 0) != *pid) {
+    fatal("waitpid failed: %s", strerror(errno));
+  }
+
+  block_signals();
+  *pid = 0;
+  unblock_signals();
+
+  if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) {
+    return -1;
+  }
+
+  return WEXITSTATUS(status);
 }
 #endif
 
 // Find an executable by name in $PATH. Exclude any that are links to
 // exclude_name.
-char *
-find_executable(const char *name, const char *exclude_name)
+char*
+find_executable(const char* name, const char* exclude_name)
 {
-       if (is_absolute_path(name)) {
-               return x_strdup(name);
-       }
-
-       char *path = conf->path;
-       if (str_eq(path, "")) {
-               path = getenv("PATH");
-       }
-       if (!path) {
-               cc_log("No PATH variable");
-               return NULL;
-       }
-
-       return find_executable_in_path(name, exclude_name, path);
+  if (is_absolute_path(name)) {
+    return x_strdup(name);
+  }
+
+  char* path = conf->path;
+  if (str_eq(path, "")) {
+    path = getenv("PATH");
+  }
+  if (!path) {
+    cc_log("No PATH variable");
+    return NULL;
+  }
+
+  return find_executable_in_path(name, exclude_name, path);
 }
 
-static char *
-find_executable_in_path(const char *name, const char *exclude_name, char *path)
+static char*
+find_executable_in_path(const char* name, const char* exclude_name, char* path)
 {
-       path = x_strdup(path);
-
-       // Search the path looking for the first compiler of the right name that
-       // isn't us.
-       char *saveptr = NULL;
-       for (char *tok = strtok_r(path, PATH_DELIM, &saveptr);
-            tok;
-            tok = strtok_r(NULL, PATH_DELIM, &saveptr)) {
+  path = x_strdup(path);
+
+  // Search the path looking for the first compiler of the right name that
+  // isn't us.
+  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);
-               if (!ret) {
-                       char *exename = format("%s.exe", name);
-                       ret = SearchPath(tok, exename, NULL, sizeof(namebuf), namebuf, NULL);
-                       free(exename);
-               }
-               (void) exclude_name;
-               if (ret) {
-                       free(path);
-                       return x_strdup(namebuf);
-               }
+    char namebuf[MAX_PATH];
+    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);
+      free(exename);
+    }
+    (void)exclude_name;
+    if (ret) {
+      free(path);
+      return x_strdup(namebuf);
+    }
 #else
-               struct stat st1, st2;
-               char *fname = format("%s/%s", tok, name);
-               // Look for a normal executable file.
-               if (access(fname, X_OK) == 0 &&
-                   lstat(fname, &st1) == 0 &&
-                   stat(fname, &st2) == 0 &&
-                   S_ISREG(st2.st_mode)) {
-                       if (S_ISLNK(st1.st_mode)) {
-                               char *buf = x_realpath(fname);
-                               if (buf) {
-                                       char *p = x_basename(buf);
-                                       if (str_eq(p, exclude_name)) {
-                                               // It's a link to "ccache"!
-                                               free(p);
-                                               free(buf);
-                                               continue;
-                                       }
-                                       free(buf);
-                                       free(p);
-                               }
-                       }
-
-                       // Found it!
-                       free(path);
-                       return fname;
-               }
-               free(fname);
+    struct stat st1, st2;
+    char* fname = format("%s/%s", tok, name);
+    // Look for a normal executable file.
+    if (access(fname, X_OK) == 0 && lstat(fname, &st1) == 0
+        && stat(fname, &st2) == 0 && S_ISREG(st2.st_mode)) {
+      if (S_ISLNK(st1.st_mode)) {
+        char* buf = x_realpath(fname);
+        if (buf) {
+          char* p = x_basename(buf);
+          if (str_eq(p, exclude_name)) {
+            // It's a link to "ccache"!
+            free(p);
+            free(buf);
+            continue;
+          }
+          free(buf);
+          free(p);
+        }
+      }
+
+      // Found it!
+      free(path);
+      return fname;
+    }
+    free(fname);
 #endif
-       }
+  }
 
-       free(path);
-       return NULL;
+  free(path);
+  return NULL;
 }
 
 void
-print_command(FILE *fp, char **argv)
+print_command(FILE* fp, char** argv)
 {
-       for (int i = 0; argv[i]; i++) {
-               fprintf(fp, "%s%s",  (i == 0) ? "" : " ", argv[i]);
-       }
-       fprintf(fp, "\n");
+  for (int i = 0; argv[i]; i++) {
+    fprintf(fp, "%s%s", (i == 0) ? "" : " ", argv[i]);
+  }
+  fprintf(fp, "\n");
 }
 
-char *
+char*
 format_command(const char* const* argv)
 {
-       size_t len = 0;
-       for (int i = 0; argv[i]; i++) {
-               len += (i == 0) ? 0 : 1;
-               len += strlen(argv[i]);
-       }
-       len += 1;
-       char *buf = static_cast<char*>(x_malloc(len + 1));
-       char *p = buf;
-       for (int i = 0; argv[i]; i++) {
-               if (i != 0) {
-                       *p++ = ' ';
-               }
-               for (const char *q = argv[i]; *q != '\0'; q++) {
-                       *p++ = *q;
-               }
-       }
-       *p++ = '\n';
-       *p++ = '\0';
-       return buf;
+  size_t len = 0;
+  for (int i = 0; argv[i]; i++) {
+    len += (i == 0) ? 0 : 1;
+    len += strlen(argv[i]);
+  }
+  len += 1;
+  char* buf = static_cast<char*>(x_malloc(len + 1));
+  char* p = buf;
+  for (int i = 0; argv[i]; i++) {
+    if (i != 0) {
+      *p++ = ' ';
+    }
+    for (const char* q = argv[i]; *q != '\0'; q++) {
+      *p++ = *q;
+    }
+  }
+  *p++ = '\n';
+  *p++ = '\0';
+  return buf;
 }
index bc0562f74ddfe96b187933ed005357a9b533aab2..32dfbdfae4d68b43008267e48fc473466947cf8a 100644 (file)
 
 #include "ccache.hpp"
 
-struct exit_function {
-       void (*function)(void *);
-       void *context;
-       struct exit_function *next;
+struct exit_function
+{
+  void (*function)(void*);
+  void* context;
+  struct exit_function* next;
 };
 
-struct nullary_exit_function {
-       void (*function)(void);
+struct nullary_exit_function
+{
+  void (*function)(void);
 };
 
-static struct exit_function *exit_functions;
+static struct exit_functionexit_functions;
 
 static void
-call_nullary_exit_function(void *context)
+call_nullary_exit_function(voidcontext)
 {
-       struct nullary_exit_function *p = (struct nullary_exit_function *)context;
-       p->function();
-       free(p);
+  struct nullary_exit_function* p = (struct nullary_exit_function*)context;
+  p->function();
+  free(p);
 }
 
 // Initialize exit functions. Must be called once before exitfn_add* are used.
 void
 exitfn_init(void)
 {
-       if (atexit(exitfn_call) != 0) {
-               fatal("atexit failed: %s", strerror(errno));
-       }
+  if (atexit(exitfn_call) != 0) {
+    fatal("atexit failed: %s", strerror(errno));
+  }
 }
 
 // Add a nullary function to be called when ccache exits. Functions are called
@@ -52,51 +54,51 @@ exitfn_init(void)
 void
 exitfn_add_nullary(void (*function)(void))
 {
-       auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
-       p->function = reinterpret_cast<void (*)(void*)>(function);
-       exitfn_add(call_nullary_exit_function, p);
+  auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
+  p->function = reinterpret_cast<void (*)(void*)>(function);
+  exitfn_add(call_nullary_exit_function, p);
 }
 
 // Add a function to be called with a context parameter when ccache exits.
 // Functions are called in LIFO order except when added via exitfn_add_last.
 void
-exitfn_add(void (*function)(void *), void *context)
+exitfn_add(void (*function)(void*), void* context)
 {
-       auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
-       p->function = function;
-       p->context = context;
-       p->next = exit_functions;
-       exit_functions = p;
+  auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
+  p->function = function;
+  p->context = context;
+  p->next = exit_functions;
+  exit_functions = p;
 }
 
 // Add a function to be called with a context parameter when ccache exits. In
 // contrast to exitfn_add, exitfn_add_last sets up the function to be called
 // last.
 void
-exitfn_add_last(void (*function)(void *), void *context)
+exitfn_add_last(void (*function)(void*), void* context)
 {
-       auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
-       p->function = function;
-       p->context = context;
-       p->next = NULL;
+  auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
+  p->function = function;
+  p->context = context;
+  p->next = NULL;
 
-       struct exit_function **q = &exit_functions;
-       while (*q) {
-               q = &(*q)->next;
-       }
-       *q = p;
+  struct exit_function** q = &exit_functions;
+  while (*q) {
+    q = &(*q)->next;
+  }
+  *q = p;
 }
 
 // Call added functions.
 void
 exitfn_call(void)
 {
-       struct exit_function *p = exit_functions;
-       exit_functions = NULL;
-       while (p) {
-               p->function(p->context);
-               struct exit_function *q = p;
-               p = p->next;
-               free(q);
-       }
+  struct exit_function* p = exit_functions;
+  exit_functions = NULL;
+  while (p) {
+    p->function(p->context);
+    struct exit_function* q = p;
+    p = p->next;
+    free(q);
+  }
 }
index b3d6d46898d7274ebc97e9fcdca757660cb67ec0..83dc47031b0503f635824c6b69b460e6f17e90e9 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "ccache.hpp"
 #include "hash.hpp"
+
+#include "ccache.hpp"
+
 #include <blake2.h>
 
 #define HASH_DELIMITER "\000cCaChE"
 
-struct hash {
-       blake2b_state state;
-       FILE *debug_binary;
-       FILE *debug_text;
+struct hash
+{
+  blake2b_state state;
+  FILE* debug_binary;
+  FILE* debug_text;
 };
 
 void
-digest_as_string(const struct digest *d, char *buffer)
+digest_as_string(const struct digest* d, char* buffer)
 {
-       format_hex(d->bytes, DIGEST_SIZE, buffer);
+  format_hex(d->bytes, DIGEST_SIZE, buffer);
 }
 
 bool
-digests_equal(const struct digest *d1, const struct digest *d2)
+digests_equal(const struct digest* d1, const struct digest* d2)
 {
-       return memcmp(d1->bytes, d2->bytes, DIGEST_SIZE) == 0;
+  return memcmp(d1->bytes, d2->bytes, DIGEST_SIZE) == 0;
 }
 
 static void
-do_hash_buffer(struct hash *hash, const void *s, size_t len)
+do_hash_buffer(struct hash* hash, const void* s, size_t len)
 {
-       assert(s);
+  assert(s);
 
-       blake2b_update(&hash->state, (const uint8_t *)s, len);
-       if (len > 0 && hash->debug_binary) {
-               (void) fwrite(s, 1, len, hash->debug_binary);
-       }
+  blake2b_update(&hash->state, (const uint8_t*)s, len);
+  if (len > 0 && hash->debug_binary) {
+    (void)fwrite(s, 1, len, hash->debug_binary);
+  }
 }
 
 static void
-do_debug_text(struct hash *hash, const void *s, size_t len)
+do_debug_text(struct hash* hash, const void* s, size_t len)
 {
-       if (len > 0 && hash->debug_text) {
-               (void) fwrite(s, 1, len, hash->debug_text);
-       }
+  if (len > 0 && hash->debug_text) {
+    (void)fwrite(s, 1, len, hash->debug_text);
+  }
 }
 
-struct hash *
+struct hash*
 hash_init(void)
 {
-       auto hash = static_cast<struct hash*>(malloc(sizeof(struct hash)));
-       blake2b_init(&hash->state, DIGEST_SIZE);
-       hash->debug_binary = NULL;
-       hash->debug_text = NULL;
-       return hash;
+  auto hash = static_cast<struct hash*>(malloc(sizeof(struct hash)));
+  blake2b_init(&hash->state, DIGEST_SIZE);
+  hash->debug_binary = NULL;
+  hash->debug_text = NULL;
+  return hash;
 }
 
-struct hash *
-hash_copy(struct hash *hash)
+struct hash*
+hash_copy(struct hashhash)
 {
-       auto result = static_cast<struct hash*>(malloc(sizeof(struct hash)));
-       result->state = hash->state;
-       result->debug_binary = NULL;
-       result->debug_text = NULL;
-       return result;
+  auto result = static_cast<struct hash*>(malloc(sizeof(struct hash)));
+  result->state = hash->state;
+  result->debug_binary = NULL;
+  result->debug_text = NULL;
+  return result;
 }
 
-void hash_free(struct hash *hash)
+void
+hash_free(struct hash* hash)
 {
-       free(hash);
+  free(hash);
 }
 
-void hash_enable_debug(
-       struct hash *hash, const char *section_name,
-       FILE *debug_binary, FILE *debug_text)
+void
+hash_enable_debug(struct hash* hash,
+                  const char* section_name,
+                  FILE* debug_binary,
+                  FILE* debug_text)
 {
-       hash->debug_binary = debug_binary;
-       hash->debug_text = debug_text;
+  hash->debug_binary = debug_binary;
+  hash->debug_text = debug_text;
 
-       do_debug_text(hash, "=== ", 4);
-       do_debug_text(hash, section_name, strlen(section_name));
-       do_debug_text(hash, " ===\n", 5);
+  do_debug_text(hash, "=== ", 4);
+  do_debug_text(hash, section_name, strlen(section_name));
+  do_debug_text(hash, " ===\n", 5);
 }
 
 void
-hash_buffer(struct hash *hash, const void *s, size_t len)
+hash_buffer(struct hash* hash, const void* s, size_t len)
 {
-       do_hash_buffer(hash, s, len);
-       do_debug_text(hash, s, len);
+  do_hash_buffer(hash, s, len);
+  do_debug_text(hash, s, len);
 }
 
 void
-hash_result_as_bytes(struct hash *hash, struct digest *digest)
+hash_result_as_bytes(struct hash* hash, struct digest* digest)
 {
-       // make a copy before altering state
-       struct hash *copy = hash_copy(hash);
-       blake2b_final(&copy->state, digest->bytes, DIGEST_SIZE);
-       hash_free(copy);
+  // make a copy before altering state
+  struct hash* copy = hash_copy(hash);
+  blake2b_final(&copy->state, digest->bytes, DIGEST_SIZE);
+  hash_free(copy);
 }
 
 void
-hash_result_as_string(struct hash *hash, char *buffer)
+hash_result_as_string(struct hash* hash, char* buffer)
 {
-       struct digest d;
-       hash_result_as_bytes(hash, &d);
-       digest_as_string(&d, buffer);
+  struct digest d;
+  hash_result_as_bytes(hash, &d);
+  digest_as_string(&d, buffer);
 }
 
 void
-hash_delimiter(struct hash *hash, const char *type)
+hash_delimiter(struct hash* hash, const char* type)
 {
-       do_hash_buffer(hash, HASH_DELIMITER, sizeof(HASH_DELIMITER));
-       do_hash_buffer(hash, type, strlen(type) + 1); // Include NUL.
-       do_debug_text(hash, "### ", 4);
-       do_debug_text(hash, type, strlen(type));
-       do_debug_text(hash, "\n", 1);
+  do_hash_buffer(hash, HASH_DELIMITER, sizeof(HASH_DELIMITER));
+  do_hash_buffer(hash, type, strlen(type) + 1); // Include NUL.
+  do_debug_text(hash, "### ", 4);
+  do_debug_text(hash, type, strlen(type));
+  do_debug_text(hash, "\n", 1);
 }
 
 void
-hash_string(struct hash *hash, const char *s)
+hash_string(struct hash* hash, const char* s)
 {
-       hash_string_buffer(hash, s, strlen(s));
+  hash_string_buffer(hash, s, strlen(s));
 }
 
 void
-hash_string_buffer(struct hash *hash, const char *s, int length)
+hash_string_buffer(struct hash* hash, const char* s, int length)
 {
-       hash_buffer(hash, s, length);
-       do_debug_text(hash, "\n", 1);
+  hash_buffer(hash, s, length);
+  do_debug_text(hash, "\n", 1);
 }
 
 void
-hash_int(struct hash *hash, int x)
+hash_int(struct hashhash, int x)
 {
-       do_hash_buffer(hash, (char *)&x, sizeof(x));
+  do_hash_buffer(hash, (char*)&x, sizeof(x));
 
-       char buf[16];
-       snprintf(buf, sizeof(buf), "%d", x);
-       do_debug_text(hash, buf, strlen(buf));
-       do_debug_text(hash, "\n", 1);
+  char buf[16];
+  snprintf(buf, sizeof(buf), "%d", x);
+  do_debug_text(hash, buf, strlen(buf));
+  do_debug_text(hash, "\n", 1);
 }
 
 bool
-hash_fd(struct hash *hash, int fd)
+hash_fd(struct hashhash, int fd)
 {
-       char buf[READ_BUFFER_SIZE];
-       ssize_t n;
+  char buf[READ_BUFFER_SIZE];
+  ssize_t n;
 
-       while ((n = read(fd, buf, sizeof(buf))) != 0) {
-               if (n == -1 && errno != EINTR) {
-                       break;
-               }
-               if (n > 0) {
-                       do_hash_buffer(hash, buf, n);
-                       do_debug_text(hash, buf, n);
-               }
-       }
-       return n == 0;
+  while ((n = read(fd, buf, sizeof(buf))) != 0) {
+    if (n == -1 && errno != EINTR) {
+      break;
+    }
+    if (n > 0) {
+      do_hash_buffer(hash, buf, n);
+      do_debug_text(hash, buf, n);
+    }
+  }
+  return n == 0;
 }
 
 bool
-hash_file(struct hash *hash, const char *fname)
+hash_file(struct hash* hash, const char* fname)
 {
-       int fd = open(fname, O_RDONLY|O_BINARY);
-       if (fd == -1) {
-               cc_log("Failed to open %s: %s", fname, strerror(errno));
-               return false;
-       }
+  int fd = open(fname, O_RDONLY | O_BINARY);
+  if (fd == -1) {
+    cc_log("Failed to open %s: %s", fname, strerror(errno));
+    return false;
+  }
 
-       bool ret = hash_fd(hash, fd);
-       close(fd);
-       return ret;
+  bool ret = hash_fd(hash, fd);
+  close(fd);
+  return ret;
 }
index eb341b2f6c11065758c318befaa605218eb82478..43b3a29a2b16e87f7fcf6551c084af451e364013 100644 (file)
 // checksum) produced by the hash algorithm.
 struct digest
 {
-       uint8_t bytes[DIGEST_SIZE];
+  uint8_t bytes[DIGEST_SIZE];
 };
 
 // Format the digest as a NUL-terminated hex string. The string buffer must
 // contain at least DIGEST_STRING_BUFFER_SIZE bytes.
-void digest_as_string(const struct digest *d, char *buffer);
+void digest_as_string(const struct digest* d, char* buffer);
 
 // Return true if d1 and d2 are equal, else false.
-bool digests_equal(const struct digest *d1, const struct digest *d2);
+bool digests_equal(const struct digest* d1, const struct digest* d2);
 
 // struct hash represents the hash algorithm's inner state.
 struct hash;
 
 // Create a new hash state.
-struct hash *hash_init(void);
+struct hashhash_init(void);
 
 // Create a new hash state from an existing hash state.
-struct hash *hash_copy(struct hash *hash);
+struct hash* hash_copy(struct hash* hash);
 
 // Free a hash state created by hash_init or hash_copy.
-void hash_free(struct hash *hash);
+void hash_free(struct hashhash);
 
 // Enable debug logging of hashed input to a binary and a text file.
-void hash_enable_debug(
-       struct hash *hash, const char *section_name, FILE *debug_binary,
-       FILE *debug_text);
+void hash_enable_debug(struct hash* hash,
+                       const char* section_name,
+                       FILE* debug_binary,
+                       FILE* debug_text);
 
 // Retrieve the digest as bytes.
-void hash_result_as_bytes(struct hash *hash, struct digest *digest);
+void hash_result_as_bytes(struct hash* hash, struct digest* digest);
 
 // Retrieve the digest as a NUL-terminated hex string. The string buffer must
 // contain at least DIGEST_STRING_BUFFER_SIZE bytes.
-void hash_result_as_string(struct hash *hash, char *buffer);
+void hash_result_as_string(struct hash* hash, char* buffer);
 
 // Hash some data that is unlikely to occur in the input. The idea is twofold:
 //
@@ -69,31 +70,31 @@ void hash_result_as_string(struct hash *hash, char *buffer);
 //   conditional hashing of information in a safe way (e.g., if we want to hash
 //   information X if CCACHE_A is set and information Y if CCACHE_B is set,
 //   there should never be a hash collision risk).
-void hash_delimiter(struct hash *hash, const char *type);
+void hash_delimiter(struct hash* hash, const char* type);
 
 // Hash bytes in a buffer.
 //
 // If hash debugging is enabled, the bytes are written verbatim to the text
 // input file.
-void hash_buffer(struct hash *hash, const void *s, size_t len);
+void hash_buffer(struct hash* hash, const void* s, size_t len);
 
 // Hash a string.
 //
 // If hash debugging is enabled, the string is written to the text input file
 // followed by a newline.
-void hash_string(struct hash *hash, const char *s);
+void hash_string(struct hash* hash, const char* s);
 
 // Hash a string with a known size.
 //
 // If hash debugging is enabled, the string is written to the text input file
 // followed by a newline.
-void hash_string_buffer(struct hash *hash, const char *s, int length);
+void hash_string_buffer(struct hash* hash, const char* s, int length);
 
 // Hash an integer.
 //
 // If hash debugging is enabled, the integer is written in text form to the
 // text input file followed by a newline.
-void hash_int(struct hash *hash, int x);
+void hash_int(struct hashhash, int x);
 
 // Add contents of an open file to the hash.
 //
@@ -101,7 +102,7 @@ void hash_int(struct hash *hash, int x);
 // file.
 //
 // Returns true on success, otherwise false.
-bool hash_fd(struct hash *hash, int fd);
+bool hash_fd(struct hashhash, int fd);
 
 // Add contents of a file to the hash.
 //
@@ -109,4 +110,4 @@ bool hash_fd(struct hash *hash, int fd);
 // file.
 //
 // Returns true on success, otherwise false.
-bool hash_file(struct hash *hash, const char *fname);
+bool hash_file(struct hash* hash, const char* fname);
index c9848a5703679096d9d0497662c1ee407de12d3b..99888296d5d9d7929ff565d3e784265047315252 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "ccache.hpp"
 #include "hashutil.hpp"
+
+#include "ccache.hpp"
 #include "macroskip.hpp"
+
 #include "third_party/xxhash.h"
 
 unsigned
-hash_from_string(void *str)
+hash_from_string(voidstr)
 {
-       return XXH64(str, strlen((const char *)str), 0);
+  return XXH64(str, strlen((const char*)str), 0);
 }
 
 unsigned
 hash_from_int(int i)
 {
-       return XXH64(&i, sizeof(int), 0);
+  return XXH64(&i, sizeof(int), 0);
 }
 
 int
-strings_equal(void *str1, void *str2)
+strings_equal(void* str1, void* str2)
 {
-       return str_eq((const char *)str1, (const char *)str2);
+  return str_eq((const char*)str1, (const char*)str2);
 }
 
 // Search for the strings "__DATE__" and "__TIME__" in str.
@@ -44,265 +46,266 @@ strings_equal(void *str1, void *str2)
 // Returns a bitmask with HASH_SOURCE_CODE_FOUND_DATE and
 // HASH_SOURCE_CODE_FOUND_TIME set appropriately.
 int
-check_for_temporal_macros(const char *str, size_t len)
+check_for_temporal_macros(const charstr, size_t len)
 {
-       int result = 0;
+  int result = 0;
 
-       // We're using the Boyer-Moore-Horspool algorithm, which searches starting
-       // from the *end* of the needle. Our needles are 8 characters long, so i
-       // starts at 7.
-       size_t i = 7;
+  // We're using the Boyer-Moore-Horspool algorithm, which searches starting
+  // from the *end* of the needle. Our needles are 8 characters long, so i
+  // starts at 7.
+  size_t i = 7;
 
-       while (i < len) {
-               // Check whether the substring ending at str[i] has the form "__...E__". On
-               // the assumption that 'E' is less common in source than '_', we check
-               // str[i-2] first.
-               if (str[i - 2] == 'E'
-                   && str[i - 0] == '_'
-                   && str[i - 7] == '_'
-                   && str[i - 1] == '_'
-                   && str[i - 6] == '_'
-                   && (i < 8 || (str[i - 8] != '_' && !isalnum(str[i - 8])))
-                   && (i + 1 >= len || (str[i + 1] != '_' && !isalnum(str[i + 1])))) {
-                       // Check the remaining characters to see if the substring is "__DATE__"
-                       // or "__TIME__".
-                       if (str[i - 5] == 'D' && str[i - 4] == 'A' && str[i - 3] == 'T') {
-                               result |= HASH_SOURCE_CODE_FOUND_DATE;
-                       } else if (str[i - 5] == 'T' && str[i - 4] == 'I' && str[i - 3] == 'M') {
-                               result |= HASH_SOURCE_CODE_FOUND_TIME;
-                       }
-               }
+  while (i < len) {
+    // Check whether the substring ending at str[i] has the form "__...E__". On
+    // the assumption that 'E' is less common in source than '_', we check
+    // str[i-2] first.
+    if (str[i - 2] == 'E' && str[i - 0] == '_' && str[i - 7] == '_'
+        && str[i - 1] == '_' && str[i - 6] == '_'
+        && (i < 8 || (str[i - 8] != '_' && !isalnum(str[i - 8])))
+        && (i + 1 >= len || (str[i + 1] != '_' && !isalnum(str[i + 1])))) {
+      // Check the remaining characters to see if the substring is "__DATE__"
+      // or "__TIME__".
+      if (str[i - 5] == 'D' && str[i - 4] == 'A' && str[i - 3] == 'T') {
+        result |= HASH_SOURCE_CODE_FOUND_DATE;
+      } else if (str[i - 5] == 'T' && str[i - 4] == 'I' && str[i - 3] == 'M') {
+        result |= HASH_SOURCE_CODE_FOUND_TIME;
+      }
+    }
 
-               // macro_skip tells us how far we can skip forward upon seeing str[i] at
-               // the end of a substring.
-               i += macro_skip[(uint8_t)str[i]];
-       }
+    // macro_skip tells us how far we can skip forward upon seeing str[i] at
+    // the end of a substring.
+    i += macro_skip[(uint8_t)str[i]];
+  }
 
-       return result;
+  return result;
 }
 
 // Hash a string. Returns a bitmask of HASH_SOURCE_CODE_* results.
 int
-hash_source_code_string(
-       struct conf *conf, struct hash *hash, const char *str, size_t len,
-       const char *path)
+hash_source_code_string(struct conf* conf,
+                        struct hash* hash,
+                        const char* str,
+                        size_t len,
+                        const char* path)
 {
-       int result = HASH_SOURCE_CODE_OK;
+  int result = HASH_SOURCE_CODE_OK;
 
-       // Check for __DATE__ and __TIME__ if the sloppiness configuration tells us
-       // we should.
-       if (!(conf->sloppiness & SLOPPY_TIME_MACROS)) {
-               result |= check_for_temporal_macros(str, len);
-       }
+  // Check for __DATE__ and __TIME__ if the sloppiness configuration tells us
+  // we should.
+  if (!(conf->sloppiness & SLOPPY_TIME_MACROS)) {
+    result |= check_for_temporal_macros(str, len);
+  }
 
-       // Hash the source string.
-       hash_string_buffer(hash, str, len);
+  // Hash the source string.
+  hash_string_buffer(hash, str, len);
 
-       if (result & HASH_SOURCE_CODE_FOUND_DATE) {
-               // Make sure that the hash sum changes if the (potential) expansion of
-               // __DATE__ changes.
-               time_t t = time(NULL);
-               struct tm now;
-               localtime_r(&t, &now);
-               cc_log("Found __DATE__ in %s", path);
-               hash_delimiter(hash, "date");
-               hash_int(hash, now.tm_year);
-               hash_int(hash, now.tm_mon);
-               hash_int(hash, now.tm_mday);
-       }
-       if (result & HASH_SOURCE_CODE_FOUND_TIME) {
-               // We don't know for sure that the program actually uses the __TIME__
-               // macro, but we have to assume it anyway and hash the time stamp. However,
-               // that's not very useful since the chance that we get a cache hit later
-               // the same second should be quite slim... So, just signal back to the
-               // caller that __TIME__ has been found so that the direct mode can be
-               // disabled.
-               cc_log("Found __TIME__ in %s", path);
-       }
+  if (result & HASH_SOURCE_CODE_FOUND_DATE) {
+    // Make sure that the hash sum changes if the (potential) expansion of
+    // __DATE__ changes.
+    time_t t = time(NULL);
+    struct tm now;
+    localtime_r(&t, &now);
+    cc_log("Found __DATE__ in %s", path);
+    hash_delimiter(hash, "date");
+    hash_int(hash, now.tm_year);
+    hash_int(hash, now.tm_mon);
+    hash_int(hash, now.tm_mday);
+  }
+  if (result & HASH_SOURCE_CODE_FOUND_TIME) {
+    // We don't know for sure that the program actually uses the __TIME__
+    // macro, but we have to assume it anyway and hash the time stamp. However,
+    // that's not very useful since the chance that we get a cache hit later
+    // the same second should be quite slim... So, just signal back to the
+    // caller that __TIME__ has been found so that the direct mode can be
+    // disabled.
+    cc_log("Found __TIME__ in %s", path);
+  }
 
-       return result;
+  return result;
 }
 
 // Hash a file ignoring comments. Returns a bitmask of HASH_SOURCE_CODE_*
 // results.
 int
-hash_source_code_file(struct conf *conf, struct hash *hash, const char *path)
+hash_source_code_file(struct conf* conf, struct hash* hash, const char* path)
 {
-       if (is_precompiled_header(path)) {
-               if (hash_file(hash, path)) {
-                       return HASH_SOURCE_CODE_OK;
-               } else {
-                       return HASH_SOURCE_CODE_ERROR;
-               }
-       } else {
-               char *data;
-               size_t size;
-               if (!read_file(path, 0, &data, &size)) {
-                       return HASH_SOURCE_CODE_ERROR;
-               }
-               int result = hash_source_code_string(conf, hash, data, size, path);
-               free(data);
-               return result;
-       }
+  if (is_precompiled_header(path)) {
+    if (hash_file(hash, path)) {
+      return HASH_SOURCE_CODE_OK;
+    } else {
+      return HASH_SOURCE_CODE_ERROR;
+    }
+  } else {
+    char* data;
+    size_t size;
+    if (!read_file(path, 0, &data, &size)) {
+      return HASH_SOURCE_CODE_ERROR;
+    }
+    int result = hash_source_code_string(conf, hash, data, size, path);
+    free(data);
+    return result;
+  }
 }
 
 bool
-hash_command_output(struct hash *hash, const char *command,
-                    const char *compiler)
+hash_command_output(struct hash* hash,
+                    const char* command,
+                    const char* compiler)
 {
 #ifdef _WIN32
-       // Trim leading space.
-       while (isspace(*command)) {
-               command++;
-       }
+  // 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;
-       } else if (str_startswith(command,
-                                 "%compiler%") && str_eq(compiler, "echo")) {
-               command = format("cmd.exe /c \"%s%s\"", compiler, command + 10);
-               cmd = true;
-       } else {
-               command = x_strdup(command);
-               cmd = false;
-       }
+  // Add "echo" command.
+  bool cmd;
+  if (str_startswith(command, "echo")) {
+    command = format("cmd.exe /c \"%s\"", command);
+    cmd = true;
+  } else if (str_startswith(command, "%compiler%")
+             && str_eq(compiler, "echo")) {
+    command = format("cmd.exe /c \"%s%s\"", compiler, command + 10);
+    cmd = true;
+  } else {
+    command = x_strdup(command);
+    cmd = false;
+  }
 #endif
 
-       struct args *args = args_init_from_string(command);
-       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);
+  struct args* args = args_init_from_string(command);
+  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));
+  PROCESS_INFORMATION pi;
+  memset(&pi, 0x00, sizeof(pi));
+  STARTUPINFO si;
+  memset(&si, 0x00, sizeof(si));
 
-       char *path = find_executable(args->argv[0], NULL);
-       if (!path) {
-               path = args->argv[0];
-       }
-       char *sh = win32getshell(path);
-       if (sh) {
-               path = sh;
-       }
+  char* path = find_executable(args->argv[0], NULL);
+  if (!path) {
+    path = args->argv[0];
+  }
+  char* sh = win32getshell(path);
+  if (sh) {
+    path = sh;
+  }
 
-       si.cb = sizeof(STARTUPINFO);
+  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;
+  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) {
-               int length;
-               win32args = win32argvtos(sh, args->argv, &length);
-       } else {
-               win32args = (char *)command;  // quoted
-       }
-       BOOL ret =
-               CreateProcess(path, win32args, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
-       CloseHandle(pipe_out[1]);
-       args_free(args);
-       free(win32args);
-       if (!cmd) {
-               free((char *)command);  // Original argument was replaced above.
-       }
-       if (ret == 0) {
-               stats_update(STATS_COMPCHECK);
-               return false;
-       }
-       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);
-       CloseHandle(pi.hThread);
-       if (exitcode != 0) {
-               cc_log("Compiler check command returned %d", (int) exitcode);
-               stats_update(STATS_COMPCHECK);
-               return false;
-       }
-       return ok;
+  char* win32args;
+  if (!cmd) {
+    int length;
+    win32args = win32argvtos(sh, args->argv, &length);
+  } else {
+    win32args = (char*)command; // quoted
+  }
+  BOOL ret =
+    CreateProcess(path, win32args, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
+  CloseHandle(pipe_out[1]);
+  args_free(args);
+  free(win32args);
+  if (!cmd) {
+    free((char*)command); // Original argument was replaced above.
+  }
+  if (ret == 0) {
+    stats_update(STATS_COMPCHECK);
+    return false;
+  }
+  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);
+  CloseHandle(pi.hThread);
+  if (exitcode != 0) {
+    cc_log("Compiler check command returned %d", (int)exitcode);
+    stats_update(STATS_COMPCHECK);
+    return false;
+  }
+  return ok;
 #else
-       int pipefd[2];
-       if (pipe(pipefd) == -1) {
-               fatal("pipe failed");
-       }
+  int pipefd[2];
+  if (pipe(pipefd) == -1) {
+    fatal("pipe failed");
+  }
 
-       pid_t pid = fork();
-       if (pid == -1) {
-               fatal("fork failed");
-       }
+  pid_t pid = fork();
+  if (pid == -1) {
+    fatal("fork failed");
+  }
 
-       if (pid == 0) {
-               // Child.
-               close(pipefd[0]);
-               close(0);
-               dup2(pipefd[1], 1);
-               dup2(pipefd[1], 2);
-               _exit(execvp(args->argv[0], args->argv));
-               // Never reached.
-       } else {
-               // Parent.
-               args_free(args);
-               close(pipefd[1]);
-               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]);
+  if (pid == 0) {
+    // Child.
+    close(pipefd[0]);
+    close(0);
+    dup2(pipefd[1], 1);
+    dup2(pipefd[1], 2);
+    _exit(execvp(args->argv[0], args->argv));
+    // Never reached.
+  } else {
+    // Parent.
+    args_free(args);
+    close(pipefd[1]);
+    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;
-               }
-               if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
-                       cc_log("Compiler check command returned %d", WEXITSTATUS(status));
-                       stats_update(STATS_COMPCHECK);
-                       return false;
-               }
-               return ok;
-       }
+    int status;
+    if (waitpid(pid, &status, 0) != pid) {
+      cc_log("waitpid failed");
+      return false;
+    }
+    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+      cc_log("Compiler check command returned %d", WEXITSTATUS(status));
+      stats_update(STATS_COMPCHECK);
+      return false;
+    }
+    return ok;
+  }
 #endif
 }
 
 bool
-hash_multicommand_output(struct hash *hash, const char *commands,
-                         const char *compiler)
+hash_multicommand_output(struct hash* hash,
+                         const char* commands,
+                         const char* compiler)
 {
-       char *command_string = x_strdup(commands);
-       char *p = command_string;
-       char *command;
-       char *saveptr = NULL;
-       bool ok = true;
-       while ((command = strtok_r(p, ";", &saveptr))) {
-               if (!hash_command_output(hash, command, compiler)) {
-                       ok = false;
-               }
-               p = NULL;
-       }
-       free(command_string);
-       return ok;
+  char* command_string = x_strdup(commands);
+  char* p = command_string;
+  char* command;
+  char* saveptr = NULL;
+  bool ok = true;
+  while ((command = strtok_r(p, ";", &saveptr))) {
+    if (!hash_command_output(hash, command, compiler)) {
+      ok = false;
+    }
+    p = NULL;
+  }
+  free(command_string);
+  return ok;
 }
index 3a270ac4be0e8177cf5cc4b67e45694ce6ed093a..09112d1081219d7f896d07885e1f7badcd3c4d11 100644 (file)
 
 #include "conf.hpp"
 #include "hash.hpp"
+
 #include <inttypes.h>
 
-unsigned hash_from_string(void *str);
+unsigned hash_from_string(voidstr);
 unsigned hash_from_int(int i);
-int strings_equal(void *str1, void *str2);
+int strings_equal(void* str1, void* str2);
 
 #define HASH_SOURCE_CODE_OK 0
 #define HASH_SOURCE_CODE_ERROR 1
-#define        HASH_SOURCE_CODE_FOUND_DATE 2
-#define        HASH_SOURCE_CODE_FOUND_TIME 4
+#define HASH_SOURCE_CODE_FOUND_DATE 2
+#define HASH_SOURCE_CODE_FOUND_TIME 4
 
-int check_for_temporal_macros(const char *str, size_t len);
-int hash_source_code_string(
-       struct conf *conf, struct hash *hash, const char *str, size_t len,
-       const char *path);
-int hash_source_code_file(
-       struct conf *conf, struct hash *hash, const char *path);
-bool hash_command_output(struct hash *hash, const char *command,
-                         const char *compiler);
-bool hash_multicommand_output(struct hash *hash, const char *command,
-                              const char *compiler);
+int check_for_temporal_macros(const char* str, size_t len);
+int hash_source_code_string(struct conf* conf,
+                            struct hash* hash,
+                            const char* str,
+                            size_t len,
+                            const char* path);
+int
+hash_source_code_file(struct conf* conf, struct hash* hash, const char* path);
+bool hash_command_output(struct hash* hash,
+                         const char* command,
+                         const char* compiler);
+bool hash_multicommand_output(struct hash* hash,
+                              const char* command,
+                              const char* compiler);
index 24996fde4a1adb8abb8a531ef54db6bc8652dc92..47540dae2b5301c6b5f61463970e54d079b3d0a7 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#define BYTES_FROM_UINT16(bytes, uint16) \
-       do { \
-               (bytes)[0] = (uint16) >>  8 & 0xFF; \
-               (bytes)[1] = (uint16) >>  0 & 0xFF; \
-       } while (false)
+#define BYTES_FROM_UINT16(bytes, uint16)                                       \
+  do {                                                                         \
+    (bytes)[0] = (uint16) >> 8 & 0xFF;                                         \
+    (bytes)[1] = (uint16) >> 0 & 0xFF;                                         \
+  } while (false)
 
-#define UINT16_FROM_BYTES(bytes) \
-       ((uint16_t)(uint8_t)(bytes)[0] <<  8 | \
-        (uint16_t)(uint8_t)(bytes)[1] <<  0)
+#define UINT16_FROM_BYTES(bytes)                                               \
+  ((uint16_t)(uint8_t)(bytes)[0] << 8 | (uint16_t)(uint8_t)(bytes)[1] << 0)
 
-#define BYTES_FROM_UINT32(bytes, uint32) \
-       do { \
-               (bytes)[0] = (uint32) >> 24 & 0xFF; \
-               (bytes)[1] = (uint32) >> 16 & 0xFF; \
-               (bytes)[2] = (uint32) >>  8 & 0xFF; \
-               (bytes)[3] = (uint32) >>  0 & 0xFF; \
-       } while (false)
+#define BYTES_FROM_UINT32(bytes, uint32)                                       \
+  do {                                                                         \
+    (bytes)[0] = (uint32) >> 24 & 0xFF;                                        \
+    (bytes)[1] = (uint32) >> 16 & 0xFF;                                        \
+    (bytes)[2] = (uint32) >> 8 & 0xFF;                                         \
+    (bytes)[3] = (uint32) >> 0 & 0xFF;                                         \
+  } while (false)
 
-#define UINT32_FROM_BYTES(bytes) \
-       ((uint32_t)(uint8_t)(bytes)[0] << 24 | \
-        (uint32_t)(uint8_t)(bytes)[1] << 16 | \
-        (uint32_t)(uint8_t)(bytes)[2] <<  8 | \
-        (uint32_t)(uint8_t)(bytes)[3] <<  0)
+#define UINT32_FROM_BYTES(bytes)                                               \
+  ((uint32_t)(uint8_t)(bytes)[0] << 24 | (uint32_t)(uint8_t)(bytes)[1] << 16   \
+   | (uint32_t)(uint8_t)(bytes)[2] << 8 | (uint32_t)(uint8_t)(bytes)[3] << 0)
 
-#define BYTES_FROM_INT64(bytes, int64) \
-       do { \
-               (bytes)[0] = (int64) >> 56 & 0xFF; \
-               (bytes)[1] = (int64) >> 48 & 0xFF; \
-               (bytes)[2] = (int64) >> 40 & 0xFF; \
-               (bytes)[3] = (int64) >> 32 & 0xFF; \
-               (bytes)[4] = (int64) >> 24 & 0xFF; \
-               (bytes)[5] = (int64) >> 16 & 0xFF; \
-               (bytes)[6] = (int64) >>  8 & 0xFF; \
-               (bytes)[7] = (int64) >>  0 & 0xFF; \
-       } while (false)
+#define BYTES_FROM_INT64(bytes, int64)                                         \
+  do {                                                                         \
+    (bytes)[0] = (int64) >> 56 & 0xFF;                                         \
+    (bytes)[1] = (int64) >> 48 & 0xFF;                                         \
+    (bytes)[2] = (int64) >> 40 & 0xFF;                                         \
+    (bytes)[3] = (int64) >> 32 & 0xFF;                                         \
+    (bytes)[4] = (int64) >> 24 & 0xFF;                                         \
+    (bytes)[5] = (int64) >> 16 & 0xFF;                                         \
+    (bytes)[6] = (int64) >> 8 & 0xFF;                                          \
+    (bytes)[7] = (int64) >> 0 & 0xFF;                                          \
+  } while (false)
 
-#define INT64_FROM_BYTES(bytes) \
-       ((int64_t)(uint8_t)(bytes)[0] << 56 | \
-        (int64_t)(uint8_t)(bytes)[1] << 48 | \
-        (int64_t)(uint8_t)(bytes)[2] << 40 | \
-        (int64_t)(uint8_t)(bytes)[3] << 32 | \
-        (int64_t)(uint8_t)(bytes)[4] << 24 | \
-        (int64_t)(uint8_t)(bytes)[5] << 16 | \
-        (int64_t)(uint8_t)(bytes)[6] <<  8 | \
-        (int64_t)(uint8_t)(bytes)[7] <<  0)
+#define INT64_FROM_BYTES(bytes)                                                \
+  ((int64_t)(uint8_t)(bytes)[0] << 56 | (int64_t)(uint8_t)(bytes)[1] << 48     \
+   | (int64_t)(uint8_t)(bytes)[2] << 40 | (int64_t)(uint8_t)(bytes)[3] << 32   \
+   | (int64_t)(uint8_t)(bytes)[4] << 24 | (int64_t)(uint8_t)(bytes)[5] << 16   \
+   | (int64_t)(uint8_t)(bytes)[6] << 8 | (int64_t)(uint8_t)(bytes)[7] << 0)
 
-#define BYTES_FROM_UINT64(bytes, uint64) \
-       do { \
-               (bytes)[0] = (uint64) >> 56 & 0xFF; \
-               (bytes)[1] = (uint64) >> 48 & 0xFF; \
-               (bytes)[2] = (uint64) >> 40 & 0xFF; \
-               (bytes)[3] = (uint64) >> 32 & 0xFF; \
-               (bytes)[4] = (uint64) >> 24 & 0xFF; \
-               (bytes)[5] = (uint64) >> 16 & 0xFF; \
-               (bytes)[6] = (uint64) >>  8 & 0xFF; \
-               (bytes)[7] = (uint64) >>  0 & 0xFF; \
-       } while (false)
+#define BYTES_FROM_UINT64(bytes, uint64)                                       \
+  do {                                                                         \
+    (bytes)[0] = (uint64) >> 56 & 0xFF;                                        \
+    (bytes)[1] = (uint64) >> 48 & 0xFF;                                        \
+    (bytes)[2] = (uint64) >> 40 & 0xFF;                                        \
+    (bytes)[3] = (uint64) >> 32 & 0xFF;                                        \
+    (bytes)[4] = (uint64) >> 24 & 0xFF;                                        \
+    (bytes)[5] = (uint64) >> 16 & 0xFF;                                        \
+    (bytes)[6] = (uint64) >> 8 & 0xFF;                                         \
+    (bytes)[7] = (uint64) >> 0 & 0xFF;                                         \
+  } while (false)
 
-#define UINT64_FROM_BYTES(bytes) \
-       ((uint64_t)(uint8_t)(bytes)[0] << 56 | \
-        (uint64_t)(uint8_t)(bytes)[1] << 48 | \
-        (uint64_t)(uint8_t)(bytes)[2] << 40 | \
-        (uint64_t)(uint8_t)(bytes)[3] << 32 | \
-        (uint64_t)(uint8_t)(bytes)[4] << 24 | \
-        (uint64_t)(uint8_t)(bytes)[5] << 16 | \
-        (uint64_t)(uint8_t)(bytes)[6] <<  8 | \
-        (uint64_t)(uint8_t)(bytes)[7] <<  0)
+#define UINT64_FROM_BYTES(bytes)                                               \
+  ((uint64_t)(uint8_t)(bytes)[0] << 56 | (uint64_t)(uint8_t)(bytes)[1] << 48   \
+   | (uint64_t)(uint8_t)(bytes)[2] << 40 | (uint64_t)(uint8_t)(bytes)[3] << 32 \
+   | (uint64_t)(uint8_t)(bytes)[4] << 24 | (uint64_t)(uint8_t)(bytes)[5] << 16 \
+   | (uint64_t)(uint8_t)(bytes)[6] << 8 | (uint64_t)(uint8_t)(bytes)[7] << 0)
index 24b99ff00780df745c76ca1b9f5ca2ab135863dd..4b32f95f4595b6bcbb852219b1da5dbeea0a77f9 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "ccache.hpp"
-
 #include "language.hpp"
 
+#include "ccache.hpp"
+
 // Supported file extensions and corresponding languages (as in parameter to
 // the -x option).
-static const struct {
-       const char *extension;
-       const char *language;
+//
+// clang-format off
+static const struct
+{
+  const char* extension;
+  const char* language;
 } extensions[] = {
-       {".c",   "c"},
-       {".C",   "c++"},
-       {".cc",  "c++"},
-       {".CC",  "c++"},
-       {".cp",  "c++"},
-       {".CP",  "c++"},
-       {".cpp", "c++"},
-       {".CPP", "c++"},
-       {".cxx", "c++"},
-       {".CXX", "c++"},
-       {".c++", "c++"},
-       {".C++", "c++"},
-       {".m",   "objective-c"},
-       {".M",   "objective-c++"},
-       {".mm",  "objective-c++"},
-       {".sx",  "assembler-with-cpp"},
-       {".S",   "assembler-with-cpp"},
-       // Preprocessed:
-       {".i",   "cpp-output"},
-       {".ii",  "c++-cpp-output"},
-       {".mi",  "objective-c-cpp-output"},
-       {".mii", "objective-c++-cpp-output"},
-       {".s",   "assembler"},
-       // Header file (for precompilation):
-       {".h",   "c-header"},
-       {".H",   "c++-header"},
-       {".h++", "c++-header"},
-       {".H++", "c++-header"},
-       {".hh",  "c++-header"},
-       {".HH",  "c++-header"},
-       {".hp",  "c++-header"},
-       {".HP",  "c++-header"},
-       {".hpp", "c++-header"},
-       {".HPP", "c++-header"},
-       {".hxx", "c++-header"},
-       {".HXX", "c++-header"},
-       {".tcc", "c++-header"},
-       {".TCC", "c++-header"},
-       {".cu",  "cu"},
-       {NULL,  NULL}
-};
+    {".c", "c"},
+    {".C", "c++"},
+    {".cc", "c++"},
+    {".CC", "c++"},
+    {".cp", "c++"},
+    {".CP", "c++"},
+    {".cpp", "c++"},
+    {".CPP", "c++"},
+    {".cxx", "c++"},
+    {".CXX", "c++"},
+    {".c++", "c++"},
+    {".C++", "c++"},
+    {".m", "objective-c"},
+    {".M", "objective-c++"},
+    {".mm", "objective-c++"},
+    {".sx", "assembler-with-cpp"},
+    {".S", "assembler-with-cpp"},
+    // Preprocessed:
+    {".i", "cpp-output"},
+    {".ii", "c++-cpp-output"},
+    {".mi", "objective-c-cpp-output"},
+    {".mii", "objective-c++-cpp-output"},
+    {".s", "assembler"},
+    // Header file (for precompilation):
+    {".h", "c-header"},
+    {".H", "c++-header"},
+    {".h++", "c++-header"},
+    {".H++", "c++-header"},
+    {".hh", "c++-header"},
+    {".HH", "c++-header"},
+    {".hp", "c++-header"},
+    {".HP", "c++-header"},
+    {".hpp", "c++-header"},
+    {".HPP", "c++-header"},
+    {".hxx", "c++-header"},
+    {".HXX", "c++-header"},
+    {".tcc", "c++-header"},
+    {".TCC", "c++-header"},
+    {".cu", "cu"},
+    {NULL, NULL}};
+// clang-format on
 
 // Supported languages and corresponding preprocessed languages.
-static const struct {
-       const char *language;
-       const char *p_language;
+//
+// clang-format off
+static const struct
+{
+  const char* language;
+  const char* p_language;
 } languages[] = {
-       {"c",                        "cpp-output"},
-       {"cpp-output",               "cpp-output"},
-       {"c-header",                 "cpp-output"},
-       {"c++",                      "c++-cpp-output"},
-       {"c++-cpp-output",           "c++-cpp-output"},
-       {"c++-header",               "c++-cpp-output"},
-       {"cu",                       "cpp-output"},
-       {"objective-c",              "objective-c-cpp-output"},
-       {"objective-c-header",       "objective-c-cpp-output"},
-       {"objc-cpp-output",          "objective-c-cpp-output"},
-       {"objective-c-cpp-output",   "objective-c-cpp-output"},
-       {"objective-c++",            "objective-c++-cpp-output"},
-       {"objc++-cpp-output",        "objective-c++-cpp-output"},
-       {"objective-c++-header",     "objective-c++-cpp-output"},
-       {"objective-c++-cpp-output", "objective-c++-cpp-output"},
-       {"assembler-with-cpp",       "assembler"},
-       {"assembler",                "assembler"},
-       {NULL,  NULL}
-};
+    {"c", "cpp-output"},
+    {"cpp-output", "cpp-output"},
+    {"c-header", "cpp-output"},
+    {"c++", "c++-cpp-output"},
+    {"c++-cpp-output", "c++-cpp-output"},
+    {"c++-header", "c++-cpp-output"},
+    {"cu", "cpp-output"},
+    {"objective-c", "objective-c-cpp-output"},
+    {"objective-c-header", "objective-c-cpp-output"},
+    {"objc-cpp-output", "objective-c-cpp-output"},
+    {"objective-c-cpp-output", "objective-c-cpp-output"},
+    {"objective-c++", "objective-c++-cpp-output"},
+    {"objc++-cpp-output", "objective-c++-cpp-output"},
+    {"objective-c++-header", "objective-c++-cpp-output"},
+    {"objective-c++-cpp-output", "objective-c++-cpp-output"},
+    {"assembler-with-cpp", "assembler"},
+    {"assembler", "assembler"},
+    {NULL, NULL}};
+// clang-format on
 
 // Guess the language of a file based on its extension. Returns NULL if the
 // extension is unknown.
-const char *
-language_for_file(const char *fname)
+const char*
+language_for_file(const charfname)
 {
-       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;
-               }
-       }
-       return NULL;
+  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;
+    }
+  }
+  return NULL;
 }
 
 // Return the preprocessed language for a given language, or NULL if unknown.
-const char *
-p_language_for_language(const char *language)
+const char*
+p_language_for_language(const charlanguage)
 {
-       if (!language) {
-               return NULL;
-       }
-       for (int i = 0; languages[i].language; ++i) {
-               if (str_eq(language, languages[i].language)) {
-                       return languages[i].p_language;
-               }
-       }
-       return NULL;
+  if (!language) {
+    return NULL;
+  }
+  for (int i = 0; languages[i].language; ++i) {
+    if (str_eq(language, languages[i].language)) {
+      return languages[i].p_language;
+    }
+  }
+  return NULL;
 }
 
 // Return the default file extension (including dot) for a language, or NULL if
 // unknown.
-const char *
-extension_for_language(const char *language)
+const char*
+extension_for_language(const charlanguage)
 {
-       if (!language) {
-               return NULL;
-       }
-       for (int i = 0; extensions[i].extension; i++) {
-               if (str_eq(language, extensions[i].language)) {
-                       return extensions[i].extension;
-               }
-       }
-       return NULL;
+  if (!language) {
+    return NULL;
+  }
+  for (int i = 0; extensions[i].extension; i++) {
+    if (str_eq(language, extensions[i].language)) {
+      return extensions[i].extension;
+    }
+  }
+  return NULL;
 }
 
 bool
-language_is_supported(const char *language)
+language_is_supported(const charlanguage)
 {
-       return p_language_for_language(language) != NULL;
+  return p_language_for_language(language) != NULL;
 }
 
 bool
-language_is_preprocessed(const char *language)
+language_is_preprocessed(const charlanguage)
 {
-       const char *p_language = p_language_for_language(language);
-       assert(p_language);
-       return str_eq(language, p_language);
+  const char* p_language = p_language_for_language(language);
+  assert(p_language);
+  return str_eq(language, p_language);
 }
index f119ece867414e4424f1caf821fec021cd8ef806..481d608ddb44925e44be035edce7fb270b4c48ea 100644 (file)
@@ -20,8 +20,8 @@
 
 #include <stdbool.h>
 
-const char *language_for_file(const char *fname);
-const char *p_language_for_language(const char *language);
-const char *extension_for_language(const char *language);
-bool language_is_supported(const char *language);
-bool language_is_preprocessed(const char *language);
+const char* language_for_file(const char* fname);
+const char* p_language_for_language(const char* language);
+const char* extension_for_language(const char* language);
+bool language_is_supported(const charlanguage);
+bool language_is_preprocessed(const charlanguage);
index d904b190ade3e6f9840377b206f5191d7e540b9d..c717d09152c271c3ca2b914b78d97bf4151cd95f 100644 (file)
 // probably be made with an atomic rename(2) to avoid corruption in the rare
 // case that the lock is broken by another process.
 bool
-lockfile_acquire(const char *path, unsigned staleness_limit)
+lockfile_acquire(const charpath, unsigned staleness_limit)
 {
-       char *lockfile = format("%s.lock", path);
-       char *my_content = NULL;
-       char *content = NULL;
-       char *initial_content = NULL;
-       const char *hostname = get_hostname();
-       bool acquired = false;
-       unsigned to_sleep = 1000; // Microseconds.
-       unsigned slept = 0; // Microseconds.
+  char* lockfile = format("%s.lock", path);
+  char* my_content = NULL;
+  char* content = NULL;
+  char* initial_content = NULL;
+  const char* hostname = get_hostname();
+  bool acquired = false;
+  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));
+  while (true) {
+    free(my_content);
+    my_content = format("%s:%d:%d", hostname, (int)getpid(), (int)time(NULL));
 
 #if defined(_WIN32) || defined(__CYGWIN__)
-               int fd = open(lockfile, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0666);
-               if (fd == -1) {
-                       int saved_errno = errno;
-                       cc_log("lockfile_acquire: open WRONLY %s: %s", lockfile, strerror(errno));
-                       if (saved_errno == ENOENT) {
-                               // Directory doesn't exist?
-                               if (create_parent_dirs(lockfile) == 0) {
-                                       // OK. Retry.
-                                       continue;
-                               }
-                       }
-                       if (saved_errno != EEXIST) {
-                               // Directory doesn't exist or isn't writable?
-                               goto out;
-                       }
-                       // Someone else has the lock.
-                       fd = open(lockfile, O_RDONLY|O_BINARY);
-                       if (fd == -1) {
-                               if (errno == ENOENT) {
-                                       // The file was removed after the open() call above, so retry
-                                       // acquiring it.
-                                       continue;
-                               } else {
-                                       cc_log("lockfile_acquire: open RDONLY %s: %s",
-                                              lockfile, strerror(errno));
-                                       goto out;
-                               }
-                       }
-                       free(content);
-                       const size_t bufsize = 1024;
-                       content = static_cast<char*>(x_malloc(bufsize));
-                       int len = read(fd, content, bufsize - 1);
-                       if (len == -1) {
-                               cc_log("lockfile_acquire: read %s: %s", lockfile, strerror(errno));
-                               close(fd);
-                               goto out;
-                       }
-                       close(fd);
-                       content[len] = '\0';
-               } else {
-                       // We got the lock.
-                       if (write(fd, my_content, strlen(my_content)) == -1) {
-                               cc_log("lockfile_acquire: write %s: %s", lockfile, strerror(errno));
-                               close(fd);
-                               x_unlink(lockfile);
-                               goto out;
-                       }
-                       close(fd);
-                       acquired = true;
-                       goto out;
-               }
+    int fd = open(lockfile, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0666);
+    if (fd == -1) {
+      int saved_errno = errno;
+      cc_log("lockfile_acquire: open WRONLY %s: %s", lockfile, strerror(errno));
+      if (saved_errno == ENOENT) {
+        // Directory doesn't exist?
+        if (create_parent_dirs(lockfile) == 0) {
+          // OK. Retry.
+          continue;
+        }
+      }
+      if (saved_errno != EEXIST) {
+        // Directory doesn't exist or isn't writable?
+        goto out;
+      }
+      // Someone else has the lock.
+      fd = open(lockfile, O_RDONLY | O_BINARY);
+      if (fd == -1) {
+        if (errno == ENOENT) {
+          // The file was removed after the open() call above, so retry
+          // acquiring it.
+          continue;
+        } else {
+          cc_log(
+            "lockfile_acquire: open RDONLY %s: %s", lockfile, strerror(errno));
+          goto out;
+        }
+      }
+      free(content);
+      const size_t bufsize = 1024;
+      content = static_cast<char*>(x_malloc(bufsize));
+      int len = read(fd, content, bufsize - 1);
+      if (len == -1) {
+        cc_log("lockfile_acquire: read %s: %s", lockfile, strerror(errno));
+        close(fd);
+        goto out;
+      }
+      close(fd);
+      content[len] = '\0';
+    } else {
+      // We got the lock.
+      if (write(fd, my_content, strlen(my_content)) == -1) {
+        cc_log("lockfile_acquire: write %s: %s", lockfile, strerror(errno));
+        close(fd);
+        x_unlink(lockfile);
+        goto out;
+      }
+      close(fd);
+      acquired = true;
+      goto out;
+    }
 #else
-               if (symlink(my_content, lockfile) == 0) {
-                       // We got the lock.
-                       acquired = true;
-                       goto out;
-               }
-               int saved_errno = errno;
-               cc_log("lockfile_acquire: symlink %s: %s", lockfile, strerror(saved_errno));
-               if (saved_errno == ENOENT) {
-                       // Directory doesn't exist?
-                       if (create_parent_dirs(lockfile) == 0) {
-                               // OK. Retry.
-                               continue;
-                       }
-               }
-               if (saved_errno == EPERM) {
-                       // The file system does not support symbolic links. We have no choice but
-                       // to grant the lock anyway.
-                       acquired = true;
-                       goto out;
-               }
-               if (saved_errno != EEXIST) {
-                       // Directory doesn't exist or isn't writable?
-                       goto out;
-               }
-               free(content);
-               content = x_readlink(lockfile);
-               if (!content) {
-                       if (errno == ENOENT) {
-                               // The symlink was removed after the symlink() call above, so retry
-                               // acquiring it.
-                               continue;
-                       } else {
-                               cc_log("lockfile_acquire: readlink %s: %s", lockfile, strerror(errno));
-                               goto out;
-                       }
-               }
+    if (symlink(my_content, lockfile) == 0) {
+      // We got the lock.
+      acquired = true;
+      goto out;
+    }
+    int saved_errno = errno;
+    cc_log("lockfile_acquire: symlink %s: %s", lockfile, strerror(saved_errno));
+    if (saved_errno == ENOENT) {
+      // Directory doesn't exist?
+      if (create_parent_dirs(lockfile) == 0) {
+        // OK. Retry.
+        continue;
+      }
+    }
+    if (saved_errno == EPERM) {
+      // The file system does not support symbolic links. We have no choice but
+      // to grant the lock anyway.
+      acquired = true;
+      goto out;
+    }
+    if (saved_errno != EEXIST) {
+      // Directory doesn't exist or isn't writable?
+      goto out;
+    }
+    free(content);
+    content = x_readlink(lockfile);
+    if (!content) {
+      if (errno == ENOENT) {
+        // The symlink was removed after the symlink() call above, so retry
+        // acquiring it.
+        continue;
+      } else {
+        cc_log("lockfile_acquire: readlink %s: %s", lockfile, strerror(errno));
+        goto out;
+      }
+    }
 #endif
 
-               if (str_eq(content, my_content)) {
-                       // Lost NFS reply?
-                       cc_log("lockfile_acquire: symlink %s failed but we got the lock anyway",
-                              lockfile);
-                       acquired = true;
-                       goto out;
-               }
-               // A possible improvement here would be to check if the process holding the
-               // lock is still alive and break the lock early if it isn't.
-               cc_log("lockfile_acquire: lock info for %s: %s", lockfile, content);
-               if (!initial_content) {
-                       initial_content = x_strdup(content);
-               }
-               if (slept > staleness_limit) {
-                       if (str_eq(content, initial_content)) {
-                               // The lock seems to be stale -- break it.
-                               cc_log("lockfile_acquire: breaking %s", lockfile);
-                               // Try to acquire path.lock.lock:
-                               if (lockfile_acquire(lockfile, staleness_limit)) {
-                                       lockfile_release(path); // Remove path.lock
-                                       lockfile_release(lockfile); // Remove path.lock.lock
-                                       to_sleep = 1000;
-                                       slept = 0;
-                                       continue;
-                               }
-                       }
-                       cc_log("lockfile_acquire: gave up acquiring %s", lockfile);
-                       goto out;
-               }
-               cc_log("lockfile_acquire: failed to acquire %s; sleeping %u microseconds",
-                      lockfile, to_sleep);
-               usleep(to_sleep);
-               slept += to_sleep;
-               to_sleep *= 2;
-       }
+    if (str_eq(content, my_content)) {
+      // Lost NFS reply?
+      cc_log("lockfile_acquire: symlink %s failed but we got the lock anyway",
+             lockfile);
+      acquired = true;
+      goto out;
+    }
+    // A possible improvement here would be to check if the process holding the
+    // lock is still alive and break the lock early if it isn't.
+    cc_log("lockfile_acquire: lock info for %s: %s", lockfile, content);
+    if (!initial_content) {
+      initial_content = x_strdup(content);
+    }
+    if (slept > staleness_limit) {
+      if (str_eq(content, initial_content)) {
+        // The lock seems to be stale -- break it.
+        cc_log("lockfile_acquire: breaking %s", lockfile);
+        // Try to acquire path.lock.lock:
+        if (lockfile_acquire(lockfile, staleness_limit)) {
+          lockfile_release(path);     // Remove path.lock
+          lockfile_release(lockfile); // Remove path.lock.lock
+          to_sleep = 1000;
+          slept = 0;
+          continue;
+        }
+      }
+      cc_log("lockfile_acquire: gave up acquiring %s", lockfile);
+      goto out;
+    }
+    cc_log("lockfile_acquire: failed to acquire %s; sleeping %u microseconds",
+           lockfile,
+           to_sleep);
+    usleep(to_sleep);
+    slept += to_sleep;
+    to_sleep *= 2;
+  }
 
 out:
-       if (acquired) {
-               cc_log("Acquired lock %s", lockfile);
-       } else {
-               cc_log("Failed to acquire lock %s", lockfile);
-       }
-       free(lockfile);
-       free(my_content);
-       free(initial_content);
-       free(content);
-       return acquired;
+  if (acquired) {
+    cc_log("Acquired lock %s", lockfile);
+  } else {
+    cc_log("Failed to acquire lock %s", lockfile);
+  }
+  free(lockfile);
+  free(my_content);
+  free(initial_content);
+  free(content);
+  return acquired;
 }
 
 // Release the lockfile for the given path. Assumes that we are the legitimate
 // owner.
 void
-lockfile_release(const char *path)
+lockfile_release(const charpath)
 {
-       char *lockfile = format("%s.lock", path);
-       cc_log("Releasing lock %s", lockfile);
-       tmp_unlink(lockfile);
-       free(lockfile);
+  char* lockfile = format("%s.lock", path);
+  cc_log("Releasing lock %s", lockfile);
+  tmp_unlink(lockfile);
+  free(lockfile);
 }
 
 #ifdef TEST_LOCKFILE
 int
-main(int argc, char **argv)
+main(int argc, char** argv)
 {
-       extern char *cache_logfile;
-       cache_logfile = "/dev/stdout";
-       if (argc == 4) {
-               unsigned staleness_limit = atoi(argv[1]);
-               if (str_eq(argv[2], "acquire")) {
-                       return lockfile_acquire(argv[3], staleness_limit) == 0;
-               } else if (str_eq(argv[2], "release")) {
-                       lockfile_release(argv[3]);
-                       return 0;
-               }
-       }
-       fprintf(stderr,
-               "Usage: testlockfile <staleness_limit> <acquire|release> <path>\n");
-       return 1;
+  extern char* cache_logfile;
+  cache_logfile = "/dev/stdout";
+  if (argc == 4) {
+    unsigned staleness_limit = atoi(argv[1]);
+    if (str_eq(argv[2], "acquire")) {
+      return lockfile_acquire(argv[3], staleness_limit) == 0;
+    } else if (str_eq(argv[2], "release")) {
+      lockfile_release(argv[3]);
+      return 0;
+    }
+  }
+  fprintf(stderr,
+          "Usage: testlockfile <staleness_limit> <acquire|release> <path>\n");
+  return 1;
 }
 #endif
index 52a06b143033457a5aa877525c2c61ac1d05bf10..d8dfc5281e12688c5f6dc0c2d4bcacde89611e99 100644 (file)
 //         print ""
 
 static const uint32_t macro_skip[] = {
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  4,  8,  8,  5,  2,  8,  8,  8,  4,  8,  8,  8,  3,  8,  8,
-       8,  8,  8,  8,  3,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  1,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
-       8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 5, 2, 8, 8, 8, 4, 8, 8, 8, 3,
+  8, 8, 8, 8, 8, 8, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 8, 8, 8, 8, 8, 8, 8, 8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
 };
index 788f313f0bc15e3348c2cc0d2b2dc90f27b62626..623ade180d267861028bd0ded2f3a3fb26535dca 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
+#include "manifest.hpp"
+
 #include "ccache.hpp"
-#include "third_party/hashtable_itr.h"
-#include "hashutil.hpp"
 #include "common_header.hpp"
 #include "compression.hpp"
+#include "hashutil.hpp"
 #include "int_bytes_conversion.hpp"
-#include "manifest.hpp"
+
+#include "third_party/hashtable_itr.h"
 #include "third_party/xxhash.h"
 
 // Manifest data format
@@ -104,731 +106,737 @@ const char MANIFEST_MAGIC[4] = {'c', 'C', 'm', 'F'};
 static const uint32_t MAX_MANIFEST_ENTRIES = 100;
 static const uint32_t MAX_MANIFEST_FILE_INFO_ENTRIES = 10000;
 
-#define ccache_static_assert(e) \
-       do { enum { ccache_static_assert__ = 1/(e) }; } while (false)
+#define ccache_static_assert(e)                                                \
+  do {                                                                         \
+    enum { ccache_static_assert__ = 1 / (e) };                                 \
+  } while (false)
 
-struct file {
-       uint16_t path_len; // strlen(path)
-       char *path; // NUL-terminated
+struct file
+{
+  uint16_t path_len; // strlen(path)
+  char* path;        // NUL-terminated
 };
 
-struct file_info {
-       // Index to n_files.
-       uint32_t index;
-       // Digest of referenced file.
-       struct digest digest;
-       // Size of referenced file.
-       uint64_t fsize;
-       // mtime of referenced file.
-       int64_t mtime;
-       // ctime of referenced file.
-       int64_t ctime;
+struct file_info
+{
+  // Index to n_files.
+  uint32_t index;
+  // Digest of referenced file.
+  struct digest digest;
+  // Size of referenced file.
+  uint64_t fsize;
+  // mtime of referenced file.
+  int64_t mtime;
+  // ctime of referenced file.
+  int64_t ctime;
 };
 
-struct result {
-       // Number of entries in file_info_indexes.
-       uint32_t n_file_info_indexes;
-       // Indexes to file_infos.
-       uint32_t *file_info_indexes;
-       // Name of the result.
-       struct digest name;
+struct result
+{
+  // Number of entries in file_info_indexes.
+  uint32_t n_file_info_indexes;
+  // Indexes to file_infos.
+  uint32_t* file_info_indexes;
+  // Name of the result.
+  struct digest name;
 };
 
-struct manifest {
-       struct common_header header;
+struct manifest
+{
+  struct common_header header;
 
-       // Referenced include files.
-       uint32_t n_files;
-       struct file *files;
+  // Referenced include files.
+  uint32_t n_files;
+  struct file* files;
 
-       // Information about referenced include files.
-       uint32_t n_file_infos;
-       struct file_info *file_infos;
+  // Information about referenced include files.
+  uint32_t n_file_infos;
+  struct file_info* file_infos;
 
-       // Result names plus references to include file infos.
-       uint32_t n_results;
-       struct result *results;
+  // Result names plus references to include file infos.
+  uint32_t n_results;
+  struct result* results;
 };
 
-struct file_stats {
-       uint64_t size;
-       int64_t mtime;
-       int64_t ctime;
+struct file_stats
+{
+  uint64_t size;
+  int64_t mtime;
+  int64_t ctime;
 };
 
 static unsigned int
-hash_from_file_info(void *key)
+hash_from_file_info(voidkey)
 {
-       ccache_static_assert(sizeof(struct file_info) == 48); // No padding.
-       return XXH64(key, sizeof(struct file_info), 0);
+  ccache_static_assert(sizeof(struct file_info) == 48); // No padding.
+  return XXH64(key, sizeof(struct file_info), 0);
 }
 
 static int
-file_infos_equal(void *key1, void *key2)
+file_infos_equal(void* key1, void* key2)
 {
-       struct file_info *fi1 = (struct file_info *)key1;
-       struct file_info *fi2 = (struct file_info *)key2;
-       return fi1->index == fi2->index
-              && digests_equal(&fi1->digest, &fi2->digest)
-              && fi1->fsize == fi2->fsize
-              && fi1->mtime == fi2->mtime
-              && fi1->ctime == fi2->ctime;
+  struct file_info* fi1 = (struct file_info*)key1;
+  struct file_info* fi2 = (struct file_info*)key2;
+  return fi1->index == fi2->index && digests_equal(&fi1->digest, &fi2->digest)
+         && fi1->fsize == fi2->fsize && fi1->mtime == fi2->mtime
+         && fi1->ctime == fi2->ctime;
 }
 
 static void
-free_manifest(struct manifest *mf)
+free_manifest(struct manifestmf)
 {
-       for (uint32_t i = 0; i < mf->n_files; i++) {
-               free(mf->files[i].path);
-       }
-       free(mf->files);
-       free(mf->file_infos);
-       for (uint32_t i = 0; i < mf->n_results; i++) {
-               free(mf->results[i].file_info_indexes);
-       }
-       free(mf->results);
-       free(mf);
+  for (uint32_t i = 0; i < mf->n_files; i++) {
+    free(mf->files[i].path);
+  }
+  free(mf->files);
+  free(mf->file_infos);
+  for (uint32_t i = 0; i < mf->n_results; i++) {
+    free(mf->results[i].file_info_indexes);
+  }
+  free(mf->results);
+  free(mf);
 }
 
-#define READ_BYTES(buf, length) \
-       do { \
-               if (!decompressor->read(decompr_state, buf, length)) { \
-                       goto out; \
-               } \
-       } while (false)
-
-#define READ_UINT16(var) \
-       do { \
-               char buf_[2]; \
-               READ_BYTES(buf_, sizeof(buf_)); \
-               (var) = UINT16_FROM_BYTES(buf_); \
-       } while (false)
-
-#define READ_UINT32(var) \
-       do { \
-               char buf_[4]; \
-               READ_BYTES(buf_, sizeof(buf_)); \
-               (var) = UINT32_FROM_BYTES(buf_); \
-       } while (false)
-
-#define READ_INT64(var) \
-       do { \
-               char buf_[8]; \
-               READ_BYTES(buf_, sizeof(buf_)); \
-               (var) = INT64_FROM_BYTES(buf_); \
-       } while (false)
-
-#define READ_UINT64(var) \
-       do { \
-               char buf_[8]; \
-               READ_BYTES(buf_, sizeof(buf_)); \
-               (var) = UINT64_FROM_BYTES(buf_); \
-       } while (false)
-
-#define READ_STR(str_var, len_var) \
-       do { \
-               READ_UINT16(len_var); \
-               (str_var) = static_cast<char*>(x_malloc(len_var + 1)); \
-               READ_BYTES(str_var, len_var); \
-               str_var[len_var] = '\0'; \
-       } while (false)
-
-static struct manifest *
+#define READ_BYTES(buf, length)                                                \
+  do {                                                                         \
+    if (!decompressor->read(decompr_state, buf, length)) {                     \
+      goto out;                                                                \
+    }                                                                          \
+  } while (false)
+
+#define READ_UINT16(var)                                                       \
+  do {                                                                         \
+    char buf_[2];                                                              \
+    READ_BYTES(buf_, sizeof(buf_));                                            \
+    (var) = UINT16_FROM_BYTES(buf_);                                           \
+  } while (false)
+
+#define READ_UINT32(var)                                                       \
+  do {                                                                         \
+    char buf_[4];                                                              \
+    READ_BYTES(buf_, sizeof(buf_));                                            \
+    (var) = UINT32_FROM_BYTES(buf_);                                           \
+  } while (false)
+
+#define READ_INT64(var)                                                        \
+  do {                                                                         \
+    char buf_[8];                                                              \
+    READ_BYTES(buf_, sizeof(buf_));                                            \
+    (var) = INT64_FROM_BYTES(buf_);                                            \
+  } while (false)
+
+#define READ_UINT64(var)                                                       \
+  do {                                                                         \
+    char buf_[8];                                                              \
+    READ_BYTES(buf_, sizeof(buf_));                                            \
+    (var) = UINT64_FROM_BYTES(buf_);                                           \
+  } while (false)
+
+#define READ_STR(str_var, len_var)                                             \
+  do {                                                                         \
+    READ_UINT16(len_var);                                                      \
+    (str_var) = static_cast<char*>(x_malloc(len_var + 1));                     \
+    READ_BYTES(str_var, len_var);                                              \
+    str_var[len_var] = '\0';                                                   \
+  } while (false)
+
+static struct manifest*
 create_empty_manifest(void)
 {
-       auto mf = static_cast<manifest*>(x_malloc(sizeof(manifest)));
-       mf->n_files = 0;
-       mf->files = NULL;
-       mf->n_file_infos = 0;
-       mf->file_infos = NULL;
-       mf->n_results = 0;
-       mf->results = NULL;
-
-       return mf;
+  auto mf = static_cast<manifest*>(x_malloc(sizeof(manifest)));
+  mf->n_files = 0;
+  mf->files = NULL;
+  mf->n_file_infos = 0;
+  mf->file_infos = NULL;
+  mf->n_results = 0;
+  mf->results = NULL;
+
+  return mf;
 }
 
-static struct manifest *
-read_manifest(const char *path, char **errmsg)
+static struct manifest*
+read_manifest(const char* path, char** errmsg)
 {
-       bool success = false;
-       struct manifest *mf = create_empty_manifest();
-       struct decompressor *decompressor = NULL;
-       struct decompr_state *decompr_state = NULL;
-       *errmsg = NULL;
-       XXH64_state_t *checksum = XXH64_createState();
-       uint64_t actual_checksum;
-       uint64_t expected_checksum;
-
-       FILE *f = fopen(path, "rb");
-       if (!f) {
-               *errmsg = x_strdup("No such manifest file");
-               goto out;
-       }
-
-       if (!common_header_initialize_for_reading(
-                   &mf->header,
-                   f,
-                   MANIFEST_MAGIC,
-                   MANIFEST_VERSION,
-                   &decompressor,
-                   &decompr_state,
-                   checksum,
-                   errmsg)) {
-               goto out;
-       }
-
-       READ_UINT32(mf->n_files);
-       mf->files = static_cast<file*>(x_calloc(mf->n_files, sizeof(file)));
-       for (uint32_t i = 0; i < mf->n_files; i++) {
-               READ_STR(mf->files[i].path, mf->files[i].path_len);
-       }
-
-       READ_UINT32(mf->n_file_infos);
-       mf->file_infos =
-               static_cast<file_info*>(x_calloc(mf->n_file_infos, sizeof(file_info)));
-       for (uint32_t i = 0; i < mf->n_file_infos; i++) {
-               READ_UINT32(mf->file_infos[i].index);
-               READ_BYTES(mf->file_infos[i].digest.bytes, DIGEST_SIZE);
-               READ_UINT64(mf->file_infos[i].fsize);
-               READ_INT64(mf->file_infos[i].mtime);
-               READ_INT64(mf->file_infos[i].ctime);
-       }
-
-       READ_UINT32(mf->n_results);
-       mf->results = static_cast<result*>(x_calloc(mf->n_results, sizeof(result)));
-       for (uint32_t i = 0; i < mf->n_results; i++) {
-               READ_UINT32(mf->results[i].n_file_info_indexes);
-               mf->results[i].file_info_indexes = static_cast<uint32_t*>(
-                       x_calloc(mf->results[i].n_file_info_indexes, sizeof(uint32_t)));
-               for (uint32_t j = 0; j < mf->results[i].n_file_info_indexes; j++) {
-                       READ_UINT32(mf->results[i].file_info_indexes[j]);
-               }
-               READ_BYTES(mf->results[i].name.bytes, DIGEST_SIZE);
-       }
-
-       actual_checksum = XXH64_digest(checksum);
-       READ_UINT64(expected_checksum);
-       if (actual_checksum == expected_checksum) {
-               success = true;
-       } else {
-               *errmsg = format(
-                       "Incorrect checksum (actual %016llx, expected %016llx)",
-                       (unsigned long long)actual_checksum,
-                       (unsigned long long)expected_checksum);
-       }
+  bool success = false;
+  struct manifest* mf = create_empty_manifest();
+  struct decompressor* decompressor = NULL;
+  struct decompr_state* decompr_state = NULL;
+  *errmsg = NULL;
+  XXH64_state_t* checksum = XXH64_createState();
+  uint64_t actual_checksum;
+  uint64_t expected_checksum;
+
+  FILE* f = fopen(path, "rb");
+  if (!f) {
+    *errmsg = x_strdup("No such manifest file");
+    goto out;
+  }
+
+  if (!common_header_initialize_for_reading(&mf->header,
+                                            f,
+                                            MANIFEST_MAGIC,
+                                            MANIFEST_VERSION,
+                                            &decompressor,
+                                            &decompr_state,
+                                            checksum,
+                                            errmsg)) {
+    goto out;
+  }
+
+  READ_UINT32(mf->n_files);
+  mf->files = static_cast<file*>(x_calloc(mf->n_files, sizeof(file)));
+  for (uint32_t i = 0; i < mf->n_files; i++) {
+    READ_STR(mf->files[i].path, mf->files[i].path_len);
+  }
+
+  READ_UINT32(mf->n_file_infos);
+  mf->file_infos =
+    static_cast<file_info*>(x_calloc(mf->n_file_infos, sizeof(file_info)));
+  for (uint32_t i = 0; i < mf->n_file_infos; i++) {
+    READ_UINT32(mf->file_infos[i].index);
+    READ_BYTES(mf->file_infos[i].digest.bytes, DIGEST_SIZE);
+    READ_UINT64(mf->file_infos[i].fsize);
+    READ_INT64(mf->file_infos[i].mtime);
+    READ_INT64(mf->file_infos[i].ctime);
+  }
+
+  READ_UINT32(mf->n_results);
+  mf->results = static_cast<result*>(x_calloc(mf->n_results, sizeof(result)));
+  for (uint32_t i = 0; i < mf->n_results; i++) {
+    READ_UINT32(mf->results[i].n_file_info_indexes);
+    mf->results[i].file_info_indexes = static_cast<uint32_t*>(
+      x_calloc(mf->results[i].n_file_info_indexes, sizeof(uint32_t)));
+    for (uint32_t j = 0; j < mf->results[i].n_file_info_indexes; j++) {
+      READ_UINT32(mf->results[i].file_info_indexes[j]);
+    }
+    READ_BYTES(mf->results[i].name.bytes, DIGEST_SIZE);
+  }
+
+  actual_checksum = XXH64_digest(checksum);
+  READ_UINT64(expected_checksum);
+  if (actual_checksum == expected_checksum) {
+    success = true;
+  } else {
+    *errmsg = format("Incorrect checksum (actual %016llx, expected %016llx)",
+                     (unsigned long long)actual_checksum,
+                     (unsigned long long)expected_checksum);
+  }
 
 out:
-       if (decompressor && !decompressor->free(decompr_state)) {
-               success = false;
-       }
-       if (f) {
-               fclose(f);
-       }
-       if (checksum) {
-               XXH64_freeState(checksum);
-       }
-       if (!success) {
-               if (!*errmsg) {
-                       *errmsg = x_strdup("Corrupt manifest file");
-               }
-               free_manifest(mf);
-               mf = NULL;
-       }
-       return mf;
+  if (decompressor && !decompressor->free(decompr_state)) {
+    success = false;
+  }
+  if (f) {
+    fclose(f);
+  }
+  if (checksum) {
+    XXH64_freeState(checksum);
+  }
+  if (!success) {
+    if (!*errmsg) {
+      *errmsg = x_strdup("Corrupt manifest file");
+    }
+    free_manifest(mf);
+    mf = NULL;
+  }
+  return mf;
 }
 
-#define WRITE_BYTES(buf, length) \
-       do { \
-               if (!compressor->write(compr_state, buf, length)) { \
-                       goto out; \
-               } \
-       } while (false)
-
-#define WRITE_UINT16(var) \
-       do { \
-               char buf_[2]; \
-               BYTES_FROM_UINT16(buf_, (var)); \
-               WRITE_BYTES(buf_, sizeof(buf_)); \
-       } while (false)
-
-#define WRITE_UINT32(var) \
-       do { \
-               char buf_[4]; \
-               BYTES_FROM_UINT32(buf_, (var)); \
-               WRITE_BYTES(buf_, sizeof(buf_)); \
-       } while (false)
-
-#define WRITE_INT64(var) \
-       do { \
-               char buf_[8]; \
-               BYTES_FROM_INT64(buf_, (var)); \
-               WRITE_BYTES(buf_, sizeof(buf_)); \
-       } while (false)
-
-#define WRITE_UINT64(var) \
-       do { \
-               char buf_[8]; \
-               BYTES_FROM_UINT64(buf_, (var)); \
-               WRITE_BYTES(buf_, sizeof(buf_)); \
-       } while (false)
+#define WRITE_BYTES(buf, length)                                               \
+  do {                                                                         \
+    if (!compressor->write(compr_state, buf, length)) {                        \
+      goto out;                                                                \
+    }                                                                          \
+  } while (false)
+
+#define WRITE_UINT16(var)                                                      \
+  do {                                                                         \
+    char buf_[2];                                                              \
+    BYTES_FROM_UINT16(buf_, (var));                                            \
+    WRITE_BYTES(buf_, sizeof(buf_));                                           \
+  } while (false)
+
+#define WRITE_UINT32(var)                                                      \
+  do {                                                                         \
+    char buf_[4];                                                              \
+    BYTES_FROM_UINT32(buf_, (var));                                            \
+    WRITE_BYTES(buf_, sizeof(buf_));                                           \
+  } while (false)
+
+#define WRITE_INT64(var)                                                       \
+  do {                                                                         \
+    char buf_[8];                                                              \
+    BYTES_FROM_INT64(buf_, (var));                                             \
+    WRITE_BYTES(buf_, sizeof(buf_));                                           \
+  } while (false)
+
+#define WRITE_UINT64(var)                                                      \
+  do {                                                                         \
+    char buf_[8];                                                              \
+    BYTES_FROM_UINT64(buf_, (var));                                            \
+    WRITE_BYTES(buf_, sizeof(buf_));                                           \
+  } while (false)
 
 static bool
-write_manifest(FILE *f, const struct manifest *mf)
+write_manifest(FILE* f, const struct manifest* mf)
 {
-       int ret = false;
-       XXH64_state_t *checksum = XXH64_createState();
-
-       uint64_t content_size = COMMON_HEADER_SIZE;
-       content_size += 4; // n_files
-       for (size_t i = 0; i < mf->n_files; i++) {
-               content_size += 2 + mf->files[i].path_len;
-       }
-       content_size += 4; // n_file_infos
-       content_size += mf->n_file_infos * (4 + DIGEST_SIZE + 8 + 8 + 8);
-       content_size += 4; // n_results
-       for (size_t i = 0; i < mf->n_results; i++) {
-               content_size += 4; // n_file_info_indexes
-               content_size += mf->results[i].n_file_info_indexes * 4;
-               content_size += DIGEST_SIZE;
-       }
-       content_size += 8; // checksum
-
-       struct common_header header;
-       struct compressor *compressor;
-       struct compr_state *compr_state;
-       if (!common_header_initialize_for_writing(
-             &header,
-             f,
-             MANIFEST_MAGIC,
-             MANIFEST_VERSION,
-             compression_type_from_config(),
-             compression_level_from_config(),
-             content_size,
-             checksum,
-             &compressor,
-             &compr_state)) {
-               goto out;
-       }
-
-       WRITE_UINT32(mf->n_files);
-       for (uint32_t i = 0; i < mf->n_files; i++) {
-               WRITE_UINT16(mf->files[i].path_len);
-               WRITE_BYTES(mf->files[i].path, mf->files[i].path_len);
-       }
-
-       WRITE_UINT32(mf->n_file_infos);
-       for (uint32_t i = 0; i < mf->n_file_infos; i++) {
-               WRITE_UINT32(mf->file_infos[i].index);
-               WRITE_BYTES(mf->file_infos[i].digest.bytes, DIGEST_SIZE);
-               WRITE_UINT64(mf->file_infos[i].fsize);
-               WRITE_INT64(mf->file_infos[i].mtime);
-               WRITE_INT64(mf->file_infos[i].ctime);
-       }
-
-       WRITE_UINT32(mf->n_results);
-       for (uint32_t i = 0; i < mf->n_results; i++) {
-               WRITE_UINT32(mf->results[i].n_file_info_indexes);
-               for (uint32_t j = 0; j < mf->results[i].n_file_info_indexes; j++) {
-                       WRITE_UINT32(mf->results[i].file_info_indexes[j]);
-               }
-               WRITE_BYTES(mf->results[i].name.bytes, DIGEST_SIZE);
-       }
-
-       WRITE_UINT64(XXH64_digest(checksum));
-
-       ret = compressor->free(compr_state);
+  int ret = false;
+  XXH64_state_t* checksum = XXH64_createState();
+
+  uint64_t content_size = COMMON_HEADER_SIZE;
+  content_size += 4; // n_files
+  for (size_t i = 0; i < mf->n_files; i++) {
+    content_size += 2 + mf->files[i].path_len;
+  }
+  content_size += 4; // n_file_infos
+  content_size += mf->n_file_infos * (4 + DIGEST_SIZE + 8 + 8 + 8);
+  content_size += 4; // n_results
+  for (size_t i = 0; i < mf->n_results; i++) {
+    content_size += 4; // n_file_info_indexes
+    content_size += mf->results[i].n_file_info_indexes * 4;
+    content_size += DIGEST_SIZE;
+  }
+  content_size += 8; // checksum
+
+  struct common_header header;
+  struct compressor* compressor;
+  struct compr_state* compr_state;
+  if (!common_header_initialize_for_writing(&header,
+                                            f,
+                                            MANIFEST_MAGIC,
+                                            MANIFEST_VERSION,
+                                            compression_type_from_config(),
+                                            compression_level_from_config(),
+                                            content_size,
+                                            checksum,
+                                            &compressor,
+                                            &compr_state)) {
+    goto out;
+  }
+
+  WRITE_UINT32(mf->n_files);
+  for (uint32_t i = 0; i < mf->n_files; i++) {
+    WRITE_UINT16(mf->files[i].path_len);
+    WRITE_BYTES(mf->files[i].path, mf->files[i].path_len);
+  }
+
+  WRITE_UINT32(mf->n_file_infos);
+  for (uint32_t i = 0; i < mf->n_file_infos; i++) {
+    WRITE_UINT32(mf->file_infos[i].index);
+    WRITE_BYTES(mf->file_infos[i].digest.bytes, DIGEST_SIZE);
+    WRITE_UINT64(mf->file_infos[i].fsize);
+    WRITE_INT64(mf->file_infos[i].mtime);
+    WRITE_INT64(mf->file_infos[i].ctime);
+  }
+
+  WRITE_UINT32(mf->n_results);
+  for (uint32_t i = 0; i < mf->n_results; i++) {
+    WRITE_UINT32(mf->results[i].n_file_info_indexes);
+    for (uint32_t j = 0; j < mf->results[i].n_file_info_indexes; j++) {
+      WRITE_UINT32(mf->results[i].file_info_indexes[j]);
+    }
+    WRITE_BYTES(mf->results[i].name.bytes, DIGEST_SIZE);
+  }
+
+  WRITE_UINT64(XXH64_digest(checksum));
+
+  ret = compressor->free(compr_state);
 
 out:
-       XXH64_freeState(checksum);
-       if (!ret) {
-               cc_log("Error writing to manifest file");
-       }
-       return ret;
+  XXH64_freeState(checksum);
+  if (!ret) {
+    cc_log("Error writing to manifest file");
+  }
+  return ret;
 }
 
 static bool
-verify_result(struct conf *conf, struct manifest *mf, struct result *result,
-              struct hashtable *stated_files, struct hashtable *hashed_files)
+verify_result(struct conf* conf,
+              struct manifest* mf,
+              struct result* result,
+              struct hashtable* stated_files,
+              struct hashtable* hashed_files)
 {
-       for (uint32_t i = 0; i < result->n_file_info_indexes; i++) {
-               struct file_info *fi = &mf->file_infos[result->file_info_indexes[i]];
-               char *path = mf->files[fi->index].path;
-               auto st = static_cast<file_stats*>(hashtable_search(stated_files, path));
-               if (!st) {
-                       struct stat file_stat;
-                       if (x_stat(path, &file_stat) != 0) {
-                               return false;
-                       }
-                       st = static_cast<file_stats*>(x_malloc(sizeof(file_stats)));
-                       st->size = file_stat.st_size;
-                       st->mtime = file_stat.st_mtime;
-                       st->ctime = file_stat.st_ctime;
-                       hashtable_insert(stated_files, x_strdup(path), st);
-               }
-
-               if (fi->fsize != st->size) {
-                       return false;
-               }
-
-               // Clang stores the mtime of the included files in the precompiled header,
-               // and will error out if that header is later used without rebuilding.
-               if ((guessed_compiler == GUESSED_CLANG
-                    || guessed_compiler == GUESSED_UNKNOWN)
-                   && output_is_precompiled_header
-                   && fi->mtime != st->mtime) {
-                       cc_log("Precompiled header includes %s, which has a new mtime", path);
-                       return false;
-               }
-
-               if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) {
-                       if (!(conf->sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME)) {
-                               if (fi->mtime == st->mtime && fi->ctime == st->ctime) {
-                                       cc_log("mtime/ctime hit for %s", path);
-                                       continue;
-                               } else {
-                                       cc_log("mtime/ctime miss for %s", path);
-                               }
-                       } else {
-                               if (fi->mtime == st->mtime) {
-                                       cc_log("mtime hit for %s", path);
-                                       continue;
-                               } else {
-                                       cc_log("mtime miss for %s", path);
-                               }
-                       }
-               }
-
-               auto actual = static_cast<digest*>(hashtable_search(hashed_files, path));
-               if (!actual) {
-                       struct hash *hash = hash_init();
-                       int ret = hash_source_code_file(conf, hash, path);
-                       if (ret & HASH_SOURCE_CODE_ERROR) {
-                               cc_log("Failed hashing %s", path);
-                               hash_free(hash);
-                               return false;
-                       }
-                       if (ret & HASH_SOURCE_CODE_FOUND_TIME) {
-                               hash_free(hash);
-                               return false;
-                       }
-
-                       actual = static_cast<digest*>(malloc(sizeof(digest)));
-                       hash_result_as_bytes(hash, actual);
-                       hashtable_insert(hashed_files, x_strdup(path), actual);
-                       hash_free(hash);
-               }
-               if (!digests_equal(&fi->digest, actual)) {
-                       return false;
-               }
-       }
-
-       return true;
+  for (uint32_t i = 0; i < result->n_file_info_indexes; i++) {
+    struct file_info* fi = &mf->file_infos[result->file_info_indexes[i]];
+    char* path = mf->files[fi->index].path;
+    auto st = static_cast<file_stats*>(hashtable_search(stated_files, path));
+    if (!st) {
+      struct stat file_stat;
+      if (x_stat(path, &file_stat) != 0) {
+        return false;
+      }
+      st = static_cast<file_stats*>(x_malloc(sizeof(file_stats)));
+      st->size = file_stat.st_size;
+      st->mtime = file_stat.st_mtime;
+      st->ctime = file_stat.st_ctime;
+      hashtable_insert(stated_files, x_strdup(path), st);
+    }
+
+    if (fi->fsize != st->size) {
+      return false;
+    }
+
+    // Clang stores the mtime of the included files in the precompiled header,
+    // and will error out if that header is later used without rebuilding.
+    if ((guessed_compiler == GUESSED_CLANG
+         || guessed_compiler == GUESSED_UNKNOWN)
+        && output_is_precompiled_header && fi->mtime != st->mtime) {
+      cc_log("Precompiled header includes %s, which has a new mtime", path);
+      return false;
+    }
+
+    if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) {
+      if (!(conf->sloppiness & SLOPPY_FILE_STAT_MATCHES_CTIME)) {
+        if (fi->mtime == st->mtime && fi->ctime == st->ctime) {
+          cc_log("mtime/ctime hit for %s", path);
+          continue;
+        } else {
+          cc_log("mtime/ctime miss for %s", path);
+        }
+      } else {
+        if (fi->mtime == st->mtime) {
+          cc_log("mtime hit for %s", path);
+          continue;
+        } else {
+          cc_log("mtime miss for %s", path);
+        }
+      }
+    }
+
+    auto actual = static_cast<digest*>(hashtable_search(hashed_files, path));
+    if (!actual) {
+      struct hash* hash = hash_init();
+      int ret = hash_source_code_file(conf, hash, path);
+      if (ret & HASH_SOURCE_CODE_ERROR) {
+        cc_log("Failed hashing %s", path);
+        hash_free(hash);
+        return false;
+      }
+      if (ret & HASH_SOURCE_CODE_FOUND_TIME) {
+        hash_free(hash);
+        return false;
+      }
+
+      actual = static_cast<digest*>(malloc(sizeof(digest)));
+      hash_result_as_bytes(hash, actual);
+      hashtable_insert(hashed_files, x_strdup(path), actual);
+      hash_free(hash);
+    }
+    if (!digests_equal(&fi->digest, actual)) {
+      return false;
+    }
+  }
+
+  return true;
 }
 
-static struct hashtable *
-create_file_index_map(struct file *files, uint32_t len)
+static struct hashtable*
+create_file_index_map(struct filefiles, uint32_t len)
 {
-       struct hashtable *h =
-               create_hashtable(1000, hash_from_string, strings_equal);
-       for (uint32_t i = 0; i < len; i++) {
-               auto index = static_cast<uint32_t*>(x_malloc(sizeof(uint32_t)));
-               *index = i;
-               hashtable_insert(h, x_strdup(files[i].path), index);
-       }
-       return h;
+  struct hashtable* h = create_hashtable(1000, hash_from_string, strings_equal);
+  for (uint32_t i = 0; i < len; i++) {
+    auto index = static_cast<uint32_t*>(x_malloc(sizeof(uint32_t)));
+    *index = i;
+    hashtable_insert(h, x_strdup(files[i].path), index);
+  }
+  return h;
 }
 
-static struct hashtable *
-create_file_info_index_map(struct file_info *infos, uint32_t len)
+static struct hashtable*
+create_file_info_index_map(struct file_infoinfos, uint32_t len)
 {
-       struct hashtable *h =
-               create_hashtable(1000, hash_from_file_info, file_infos_equal);
-       for (uint32_t i = 0; i < len; i++) {
-               auto fi = static_cast<file_info*>(x_malloc(sizeof(file_info)));
-               *fi = infos[i];
-               uint32_t *index = static_cast<uint32_t*>(x_malloc(sizeof(uint32_t)));
-               *index = i;
-               hashtable_insert(h, fi, index);
-       }
-       return h;
+  struct hashtable* h =
+    create_hashtable(1000, hash_from_file_info, file_infos_equal);
+  for (uint32_t i = 0; i < len; i++) {
+    auto fi = static_cast<file_info*>(x_malloc(sizeof(file_info)));
+    *fi = infos[i];
+    uint32_t* index = static_cast<uint32_t*>(x_malloc(sizeof(uint32_t)));
+    *index = i;
+    hashtable_insert(h, fi, index);
+  }
+  return h;
 }
 
 static uint32_t
-get_include_file_index(struct manifest *mf, char *path,
-                       struct hashtable *mf_files)
+get_include_file_index(struct manifest* mf,
+                       char* path,
+                       struct hashtable* mf_files)
 {
-       uint32_t *index = static_cast<uint32_t*>(hashtable_search(mf_files, path));
-       if (index) {
-               return *index;
-       }
-
-       uint32_t n = mf->n_files;
-       mf->files = static_cast<file*>(x_realloc(mf->files, (n + 1) * sizeof(file)));
-       mf->n_files++;
-       mf->files[n].path_len = strlen(path);
-       mf->files[n].path = x_strdup(path);
-       return n;
+  uint32_t* index = static_cast<uint32_t*>(hashtable_search(mf_files, path));
+  if (index) {
+    return *index;
+  }
+
+  uint32_t n = mf->n_files;
+  mf->files = static_cast<file*>(x_realloc(mf->files, (n + 1) * sizeof(file)));
+  mf->n_files++;
+  mf->files[n].path_len = strlen(path);
+  mf->files[n].path = x_strdup(path);
+  return n;
 }
 
 static uint32_t
-get_file_info_index(struct manifest *mf,
-                    char *path,
-                    struct digest *digest,
-                    struct hashtable *mf_files,
-                    struct hashtable *mf_file_infos)
+get_file_info_index(struct manifestmf,
+                    charpath,
+                    struct digestdigest,
+                    struct hashtablemf_files,
+                    struct hashtablemf_file_infos)
 {
-       struct file_info fi;
-       fi.index = get_include_file_index(mf, path, mf_files);
-       fi.digest = *digest;
-
-       // file_stat.st_{m,c}time has a resolution of 1 second, so we can cache the
-       // file's mtime and ctime only if they're at least one second older than
-       // time_of_compilation.
-       //
-       // 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) {
-               if (time_of_compilation > MAX(file_stat.st_mtime, file_stat.st_ctime)) {
-                       fi.mtime = file_stat.st_mtime;
-                       fi.ctime = file_stat.st_ctime;
-               } else {
-                       fi.mtime = -1;
-                       fi.ctime = -1;
-               }
-               fi.fsize = file_stat.st_size;
-       } else {
-               fi.mtime = -1;
-               fi.ctime = -1;
-               fi.fsize = 0;
-       }
-
-       auto fi_index = static_cast<uint32_t*>(hashtable_search(mf_file_infos, &fi));
-       if (fi_index) {
-               return *fi_index;
-       }
-
-       uint32_t n = mf->n_file_infos;
-       mf->file_infos = static_cast<file_info*>(
-               x_realloc(mf->file_infos, (n + 1) * sizeof(file_info)));
-       mf->n_file_infos++;
-       mf->file_infos[n] = fi;
-       return n;
+  struct file_info fi;
+  fi.index = get_include_file_index(mf, path, mf_files);
+  fi.digest = *digest;
+
+  // file_stat.st_{m,c}time has a resolution of 1 second, so we can cache the
+  // file's mtime and ctime only if they're at least one second older than
+  // time_of_compilation.
+  //
+  // 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) {
+    if (time_of_compilation > MAX(file_stat.st_mtime, file_stat.st_ctime)) {
+      fi.mtime = file_stat.st_mtime;
+      fi.ctime = file_stat.st_ctime;
+    } else {
+      fi.mtime = -1;
+      fi.ctime = -1;
+    }
+    fi.fsize = file_stat.st_size;
+  } else {
+    fi.mtime = -1;
+    fi.ctime = -1;
+    fi.fsize = 0;
+  }
+
+  auto fi_index = static_cast<uint32_t*>(hashtable_search(mf_file_infos, &fi));
+  if (fi_index) {
+    return *fi_index;
+  }
+
+  uint32_t n = mf->n_file_infos;
+  mf->file_infos = static_cast<file_info*>(
+    x_realloc(mf->file_infos, (n + 1) * sizeof(file_info)));
+  mf->n_file_infos++;
+  mf->file_infos[n] = fi;
+  return n;
 }
 
 static void
-add_file_info_indexes(uint32_t *indexes, uint32_t size,
-                      struct manifest *mf, struct hashtable *included_files)
+add_file_info_indexes(uint32_t* indexes,
+                      uint32_t size,
+                      struct manifest* mf,
+                      struct hashtable* included_files)
 {
-       if (size == 0) {
-               return;
-       }
-
-       // path --> index
-       struct hashtable *mf_files = create_file_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 {
-               auto path = static_cast<char*>(hashtable_iterator_key(iter));
-               auto digest = static_cast<struct digest*>(hashtable_iterator_value(iter));
-               indexes[i] = get_file_info_index(mf, path, digest, mf_files,
-                                                mf_file_infos);
-               i++;
-       } while (hashtable_iterator_advance(iter));
-       assert(i == size);
-
-       hashtable_destroy(mf_file_infos, 1);
-       hashtable_destroy(mf_files, 1);
+  if (size == 0) {
+    return;
+  }
+
+  // path --> index
+  struct hashtable* mf_files = create_file_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 {
+    auto path = static_cast<char*>(hashtable_iterator_key(iter));
+    auto digest = static_cast<struct digest*>(hashtable_iterator_value(iter));
+    indexes[i] = get_file_info_index(mf, path, digest, mf_files, mf_file_infos);
+    i++;
+  } while (hashtable_iterator_advance(iter));
+  assert(i == size);
+
+  hashtable_destroy(mf_file_infos, 1);
+  hashtable_destroy(mf_files, 1);
 }
 
 static void
-add_result_entry(struct manifest *mf,
-                 struct digest *result_digest,
-                 struct hashtable *included_files)
+add_result_entry(struct manifestmf,
+                 struct digestresult_digest,
+                 struct hashtableincluded_files)
 {
-       uint32_t n_results = mf->n_results;
-       mf->results = static_cast<result*>(
-               x_realloc(mf->results, (n_results + 1) * sizeof(result)));
-       mf->n_results++;
-       struct result *result = &mf->results[n_results];
-
-       uint32_t n_fii = hashtable_count(included_files);
-       result->n_file_info_indexes = n_fii;
-       result->file_info_indexes = static_cast<uint32_t*>(
-               x_malloc(n_fii * sizeof(uint32_t)));
-       add_file_info_indexes(result->file_info_indexes, n_fii, mf, included_files);
-       result->name = *result_digest;
+  uint32_t n_results = mf->n_results;
+  mf->results = static_cast<result*>(
+    x_realloc(mf->results, (n_results + 1) * sizeof(result)));
+  mf->n_results++;
+  struct result* result = &mf->results[n_results];
+
+  uint32_t n_fii = hashtable_count(included_files);
+  result->n_file_info_indexes = n_fii;
+  result->file_info_indexes =
+    static_cast<uint32_t*>(x_malloc(n_fii * sizeof(uint32_t)));
+  add_file_info_indexes(result->file_info_indexes, n_fii, mf, included_files);
+  result->name = *result_digest;
 }
 
 // Try to get the result name from a manifest file. Caller frees. Returns NULL
 // on failure.
-struct digest *
-manifest_get(struct conf *conf, const char *manifest_path)
+struct digest*
+manifest_get(struct conf* conf, const char* manifest_path)
 {
-       char *errmsg;
-       struct manifest *mf = read_manifest(manifest_path, &errmsg);
-       if (!mf) {
-               cc_log("%s", errmsg);
-               return NULL;
-       }
-
-       // path --> struct digest
-       struct hashtable *hashed_files =
-               create_hashtable(1000, hash_from_string, strings_equal);
-       // path --> struct file_stats
-       struct hashtable *stated_files =
-               create_hashtable(1000, hash_from_string, strings_equal);
-
-       // Check newest result first since it's a bit more likely to match.
-       struct digest *name = NULL;
-       for (uint32_t i = mf->n_results; i > 0; i--) {
-               if (verify_result(conf, mf, &mf->results[i - 1],
-                                 stated_files, hashed_files)) {
-                       name = static_cast<digest*>(x_malloc(sizeof(digest)));
-                       *name = mf->results[i - 1].name;
-                       goto out;
-               }
-       }
+  char* errmsg;
+  struct manifest* mf = read_manifest(manifest_path, &errmsg);
+  if (!mf) {
+    cc_log("%s", errmsg);
+    return NULL;
+  }
+
+  // path --> struct digest
+  struct hashtable* hashed_files =
+    create_hashtable(1000, hash_from_string, strings_equal);
+  // path --> struct file_stats
+  struct hashtable* stated_files =
+    create_hashtable(1000, hash_from_string, strings_equal);
+
+  // Check newest result first since it's a bit more likely to match.
+  struct digest* name = NULL;
+  for (uint32_t i = mf->n_results; i > 0; i--) {
+    if (verify_result(
+          conf, mf, &mf->results[i - 1], stated_files, hashed_files)) {
+      name = static_cast<digest*>(x_malloc(sizeof(digest)));
+      *name = mf->results[i - 1].name;
+      goto out;
+    }
+  }
 
 out:
-       if (hashed_files) {
-               hashtable_destroy(hashed_files, 1);
-       }
-       if (stated_files) {
-               hashtable_destroy(stated_files, 1);
-       }
-       free_manifest(mf);
-       if (name) {
-               // Update modification timestamp to save files from LRU cleanup.
-               update_mtime(manifest_path);
-       }
-       return name;
+  if (hashed_files) {
+    hashtable_destroy(hashed_files, 1);
+  }
+  if (stated_files) {
+    hashtable_destroy(stated_files, 1);
+  }
+  free_manifest(mf);
+  if (name) {
+    // Update modification timestamp to save files from LRU cleanup.
+    update_mtime(manifest_path);
+  }
+  return name;
 }
 
 // Put the result name into a manifest file given a set of included files.
 // Returns true on success, otherwise false.
 bool
-manifest_put(const char *manifest_path, struct digest *result_name,
-             struct hashtable *included_files)
+manifest_put(const char* manifest_path,
+             struct digest* result_name,
+             struct hashtable* included_files)
 {
-       // We don't bother to acquire a lock when writing the manifest to disk. A
-       // race between two processes will only result in one lost entry, which is
-       // not a big deal, and it's also very unlikely.
-
-       char *errmsg;
-       struct manifest *mf = read_manifest(manifest_path, &errmsg);
-       if (!mf) {
-               // New or corrupt file.
-               mf = create_empty_manifest();
-               free(errmsg); // Ignore.
-       }
-
-       if (mf->n_results > MAX_MANIFEST_ENTRIES) {
-               // Normally, there shouldn't be many result entries in the manifest since
-               // new entries are added only if an include file has changed but not the
-               // source file, and you typically change source files more often than
-               // header files. However, it's certainly possible to imagine cases where
-               // the manifest will grow large (for instance, a generated header file that
-               // changes for every build), and this must be taken care of since
-               // processing an ever growing manifest eventually will take too much time.
-               // A good way of solving this would be to maintain the result entries in
-               // LRU order and discarding the old ones. An easy way is to throw away all
-               // entries when there are too many. Let's do that for now.
-               cc_log("More than %u entries in manifest file; discarding",
-                      MAX_MANIFEST_ENTRIES);
-               free_manifest(mf);
-               mf = create_empty_manifest();
-       } else if (mf->n_file_infos > MAX_MANIFEST_FILE_INFO_ENTRIES) {
-               // Rarely, file_info entries can grow large in pathological cases where
-               // many included files change, but the main file does not. This also puts
-               // an upper bound on the number of file_info entries.
-               cc_log("More than %u file_info entries in manifest file; discarding",
-                      MAX_MANIFEST_FILE_INFO_ENTRIES);
-               free_manifest(mf);
-               mf = create_empty_manifest();
-       }
-
-       add_result_entry(mf, result_name, included_files);
-
-       int ret = false;
-       char *tmp_file = format("%s.tmp", manifest_path);
-       int fd = create_tmp_fd(&tmp_file);
-       FILE *f = fdopen(fd, "wb");
-       if (!f) {
-               cc_log("Failed to fdopen %s", tmp_file);
-               goto out;
-       }
-       if (write_manifest(f, mf)) {
-               fclose(f);
-               f = NULL;
-               if (x_rename(tmp_file, manifest_path) == 0) {
-                       ret = true;
-               } else {
-                       cc_log("Failed to rename %s to %s", tmp_file, manifest_path);
-               }
-       } else {
-               cc_log("Failed to write manifest file %s", tmp_file);
-       }
+  // We don't bother to acquire a lock when writing the manifest to disk. A
+  // race between two processes will only result in one lost entry, which is
+  // not a big deal, and it's also very unlikely.
+
+  char* errmsg;
+  struct manifest* mf = read_manifest(manifest_path, &errmsg);
+  if (!mf) {
+    // New or corrupt file.
+    mf = create_empty_manifest();
+    free(errmsg); // Ignore.
+  }
+
+  if (mf->n_results > MAX_MANIFEST_ENTRIES) {
+    // Normally, there shouldn't be many result entries in the manifest since
+    // new entries are added only if an include file has changed but not the
+    // source file, and you typically change source files more often than
+    // header files. However, it's certainly possible to imagine cases where
+    // the manifest will grow large (for instance, a generated header file that
+    // changes for every build), and this must be taken care of since
+    // processing an ever growing manifest eventually will take too much time.
+    // A good way of solving this would be to maintain the result entries in
+    // LRU order and discarding the old ones. An easy way is to throw away all
+    // entries when there are too many. Let's do that for now.
+    cc_log("More than %u entries in manifest file; discarding",
+           MAX_MANIFEST_ENTRIES);
+    free_manifest(mf);
+    mf = create_empty_manifest();
+  } else if (mf->n_file_infos > MAX_MANIFEST_FILE_INFO_ENTRIES) {
+    // Rarely, file_info entries can grow large in pathological cases where
+    // many included files change, but the main file does not. This also puts
+    // an upper bound on the number of file_info entries.
+    cc_log("More than %u file_info entries in manifest file; discarding",
+           MAX_MANIFEST_FILE_INFO_ENTRIES);
+    free_manifest(mf);
+    mf = create_empty_manifest();
+  }
+
+  add_result_entry(mf, result_name, included_files);
+
+  int ret = false;
+  char* tmp_file = format("%s.tmp", manifest_path);
+  int fd = create_tmp_fd(&tmp_file);
+  FILE* f = fdopen(fd, "wb");
+  if (!f) {
+    cc_log("Failed to fdopen %s", tmp_file);
+    goto out;
+  }
+  if (write_manifest(f, mf)) {
+    fclose(f);
+    f = NULL;
+    if (x_rename(tmp_file, manifest_path) == 0) {
+      ret = true;
+    } else {
+      cc_log("Failed to rename %s to %s", tmp_file, manifest_path);
+    }
+  } else {
+    cc_log("Failed to write manifest file %s", tmp_file);
+  }
 
 out:
-       if (f) {
-               fclose(f);
-       }
-       if (mf) {
-               free_manifest(mf);
-       }
-       if (tmp_file) {
-               free(tmp_file);
-       }
-       return ret;
+  if (f) {
+    fclose(f);
+  }
+  if (mf) {
+    free_manifest(mf);
+  }
+  if (tmp_file) {
+    free(tmp_file);
+  }
+  return ret;
 }
 
 bool
-manifest_dump(const char *manifest_path, FILE *stream)
+manifest_dump(const char* manifest_path, FILE* stream)
 {
-       char *errmsg;
-       struct manifest *mf = read_manifest(manifest_path, &errmsg);
-       if (!mf) {
-               assert(errmsg);
-               fprintf(stream, "Error: %s\n", errmsg);
-               free(errmsg);
-               return false;
-       }
-
-       common_header_dump(&mf->header, stream);
-
-       fprintf(stream, "File paths (%u):\n", (unsigned)mf->n_files);
-       for (unsigned i = 0; i < mf->n_files; ++i) {
-               fprintf(stream, "  %u: %s\n", i, mf->files[i].path);
-       }
-       fprintf(stream, "File infos (%u):\n", (unsigned)mf->n_file_infos);
-       for (unsigned i = 0; i < mf->n_file_infos; ++i) {
-               char digest[DIGEST_STRING_BUFFER_SIZE];
-               fprintf(stream, "  %u:\n", i);
-               fprintf(stream, "    Path index: %u\n", mf->file_infos[i].index);
-               digest_as_string(&mf->file_infos[i].digest, digest);
-               fprintf(stream, "    Hash: %s\n", digest);
-               fprintf(stream, "    File size: %" PRIu64 "\n", mf->file_infos[i].fsize);
-               fprintf(stream, "    Mtime: %lld\n", (long long)mf->file_infos[i].mtime);
-               fprintf(stream, "    Ctime: %lld\n", (long long)mf->file_infos[i].ctime);
-       }
-       fprintf(stream, "Results (%u):\n", (unsigned)mf->n_results);
-       for (unsigned i = 0; i < mf->n_results; ++i) {
-               char name[DIGEST_STRING_BUFFER_SIZE];
-               fprintf(stream, "  %u:\n", i);
-               fprintf(stream, "    File info indexes:");
-               for (unsigned j = 0; j < mf->results[i].n_file_info_indexes; ++j) {
-                       fprintf(stream, " %u", mf->results[i].file_info_indexes[j]);
-               }
-               fprintf(stream, "\n");
-               digest_as_string(&mf->results[i].name, name);
-               fprintf(stream, "    Name: %s\n", name);
-       }
-
-       free_manifest(mf);
-       return true;
+  char* errmsg;
+  struct manifest* mf = read_manifest(manifest_path, &errmsg);
+  if (!mf) {
+    assert(errmsg);
+    fprintf(stream, "Error: %s\n", errmsg);
+    free(errmsg);
+    return false;
+  }
+
+  common_header_dump(&mf->header, stream);
+
+  fprintf(stream, "File paths (%u):\n", (unsigned)mf->n_files);
+  for (unsigned i = 0; i < mf->n_files; ++i) {
+    fprintf(stream, "  %u: %s\n", i, mf->files[i].path);
+  }
+  fprintf(stream, "File infos (%u):\n", (unsigned)mf->n_file_infos);
+  for (unsigned i = 0; i < mf->n_file_infos; ++i) {
+    char digest[DIGEST_STRING_BUFFER_SIZE];
+    fprintf(stream, "  %u:\n", i);
+    fprintf(stream, "    Path index: %u\n", mf->file_infos[i].index);
+    digest_as_string(&mf->file_infos[i].digest, digest);
+    fprintf(stream, "    Hash: %s\n", digest);
+    fprintf(stream, "    File size: %" PRIu64 "\n", mf->file_infos[i].fsize);
+    fprintf(stream, "    Mtime: %lld\n", (long long)mf->file_infos[i].mtime);
+    fprintf(stream, "    Ctime: %lld\n", (long long)mf->file_infos[i].ctime);
+  }
+  fprintf(stream, "Results (%u):\n", (unsigned)mf->n_results);
+  for (unsigned i = 0; i < mf->n_results; ++i) {
+    char name[DIGEST_STRING_BUFFER_SIZE];
+    fprintf(stream, "  %u:\n", i);
+    fprintf(stream, "    File info indexes:");
+    for (unsigned j = 0; j < mf->results[i].n_file_info_indexes; ++j) {
+      fprintf(stream, " %u", mf->results[i].file_info_indexes[j]);
+    }
+    fprintf(stream, "\n");
+    digest_as_string(&mf->results[i].name, name);
+    fprintf(stream, "    Name: %s\n", name);
+  }
+
+  free_manifest(mf);
+  return true;
 }
index 4fe9e0c7fd6b772e6ac59359420fd8c55950dc1f..05dae1e85457996fd782c6f41b256193179d037d 100644 (file)
 
 #include "conf.hpp"
 #include "hashutil.hpp"
+
 #include "third_party/hashtable.h"
 
 extern const char MANIFEST_MAGIC[4];
 #define MANIFEST_VERSION 2
 
-struct digest *manifest_get(struct conf *conf, const char *manifest_path);
-bool manifest_put(const char *manifest_path, struct digest *result_digest,
-                  struct hashtable *included_files);
-bool manifest_dump(const char *manifest_path, FILE *stream);
+struct digest* manifest_get(struct conf* conf, const char* manifest_path);
+bool manifest_put(const char* manifest_path,
+                  struct digest* result_digest,
+                  struct hashtable* included_files);
+bool manifest_dump(const char* manifest_path, FILE* stream);
index 45eac6397af74b3d5aeeb9d41ec61c6f0945f9f7..c1374e31d2eb21131aa2faa7a4299d97a0212b49 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
+#include "result.hpp"
+
 #include "ccache.hpp"
 #include "common_header.hpp"
-#include "int_bytes_conversion.hpp"
 #include "compression.hpp"
 #include "hash.hpp"
-#include "result.hpp"
+#include "int_bytes_conversion.hpp"
 
 // Result data format
 // ==================
 //
 // 1: Introduced in ccache 3.8.
 
-extern const struct conf *conf;
-extern char *stats_file;
+extern const struct confconf;
+extern charstats_file;
 
 const char RESULT_MAGIC[4] = {'c', 'C', 'r', 'S'};
 
 enum {
-       // File data stored inside the result file.
-       EMBEDDED_FILE_MARKER = 0,
+  // File data stored inside the result file.
+  EMBEDDED_FILE_MARKER = 0,
 
-       // File stored as-is in the file system.
-       RAW_FILE_MARKER = 1
+  // File stored as-is in the file system.
+  RAW_FILE_MARKER = 1
 };
 
-struct result_file {
-       char *suffix;
-       char *path;
-       uint64_t size;
+struct result_file
+{
+  char* suffix;
+  char* path;
+  uint64_t size;
 };
 
-struct result_files {
-       uint32_t n_files;
-       struct result_file *files;
-       uint64_t *sizes;
+struct result_files
+{
+  uint32_t n_files;
+  struct result_file* files;
+  uint64_t* sizes;
 };
 
-typedef bool (*read_entry_fn)(
-       struct decompressor *decompressor,
-       struct decompr_state *decompr_state,
-       const char *result_path_in_cache,
-       uint32_t entry_number,
-       const struct result_files *list,
-       FILE *dump_stream);
-
-typedef bool (*write_entry_fn)(
-       struct compressor *compressor,
-       struct compr_state *compr_state,
-       const char *result_path_in_cache,
-       uint32_t entry_number,
-       const struct result_file *file);
-
-struct result_files *
+typedef bool (*read_entry_fn)(struct decompressor* decompressor,
+                              struct decompr_state* decompr_state,
+                              const char* result_path_in_cache,
+                              uint32_t entry_number,
+                              const struct result_files* list,
+                              FILE* dump_stream);
+
+typedef bool (*write_entry_fn)(struct compressor* compressor,
+                               struct compr_state* compr_state,
+                               const char* result_path_in_cache,
+                               uint32_t entry_number,
+                               const struct result_file* file);
+
+struct result_files*
 result_files_init(void)
 {
-       auto list = static_cast<result_files*>(x_malloc(sizeof(result_files)));
-       list->n_files = 0;
-       list->files = NULL;
-       list->sizes = NULL;
+  auto list = static_cast<result_files*>(x_malloc(sizeof(result_files)));
+  list->n_files = 0;
+  list->files = NULL;
+  list->sizes = NULL;
 
-       return list;
+  return list;
 }
 
 void
-result_files_add(struct result_files *list, const char *path,
-                 const char *suffix)
+result_files_add(struct result_files* list,
+                 const char* path,
+                 const char* suffix)
 {
-       uint32_t n = list->n_files;
-       list->files = static_cast<result_file*>(
-               x_realloc(list->files, (n + 1) * sizeof(result_file)));
-       list->sizes = static_cast<uint64_t*>(
-               x_realloc(list->sizes, (n + 1) * sizeof(uint64_t)));
-       struct result_file *f = &list->files[list->n_files];
-       list->n_files++;
-
-       struct stat st;
-       x_stat(path, &st);
-
-       f->suffix = x_strdup(suffix);
-       f->path = x_strdup(path);
-       f->size = st.st_size;
+  uint32_t n = list->n_files;
+  list->files = static_cast<result_file*>(
+    x_realloc(list->files, (n + 1) * sizeof(result_file)));
+  list->sizes =
+    static_cast<uint64_t*>(x_realloc(list->sizes, (n + 1) * sizeof(uint64_t)));
+  struct result_file* f = &list->files[list->n_files];
+  list->n_files++;
+
+  struct stat st;
+  x_stat(path, &st);
+
+  f->suffix = x_strdup(suffix);
+  f->path = x_strdup(path);
+  f->size = st.st_size;
 }
 
 void
-result_files_free(struct result_files *list)
+result_files_free(struct result_fileslist)
 {
-       for (uint32_t i = 0; i < list->n_files; i++) {
-               free(list->files[i].suffix);
-               free(list->files[i].path);
-       }
-       free(list->files);
-       list->files = NULL;
-       free(list->sizes);
-       list->sizes = NULL;
-
-       free(list);
+  for (uint32_t i = 0; i < list->n_files; i++) {
+    free(list->files[i].suffix);
+    free(list->files[i].path);
+  }
+  free(list->files);
+  list->files = NULL;
+  free(list->sizes);
+  list->sizes = NULL;
+
+  free(list);
 }
 
-#define READ_BYTES(buf, length) \
-       do { \
-               if (!decompressor->read(decompr_state, buf, length)) { \
-                       goto out; \
-               } \
-       } while (false)
+#define READ_BYTES(buf, length)                                                \
+  do {                                                                         \
+    if (!decompressor->read(decompr_state, buf, length)) {                     \
+      goto out;                                                                \
+    }                                                                          \
+  } while (false)
 
-#define READ_BYTE(var) \
-       READ_BYTES(&var, 1)
+#define READ_BYTE(var) READ_BYTES(&var, 1)
 
-#define READ_UINT64(var) \
-       do { \
-               char buf_[8]; \
-               READ_BYTES(buf_, sizeof(buf_)); \
-               (var) = UINT64_FROM_BYTES(buf_); \
-       } while (false)
+#define READ_UINT64(var)                                                       \
+  do {                                                                         \
+    char buf_[8];                                                              \
+    READ_BYTES(buf_, sizeof(buf_));                                            \
+    (var) = UINT64_FROM_BYTES(buf_);                                           \
+  } while (false)
 
 static bool
-read_embedded_file_entry(
-       struct decompressor *decompressor,
-       struct decompr_state *decompr_state,
-       const char *result_path_in_cache,
-       uint32_t entry_number,
-       const struct result_files *list,
-       FILE *dump_stream)
+read_embedded_file_entry(struct decompressor* decompressor,
+                         struct decompr_state* decompr_state,
+                         const char* result_path_in_cache,
+                         uint32_t entry_number,
+                         const struct result_files* list,
+                         FILE* dump_stream)
 {
-       (void)result_path_in_cache;
-       bool found = false;
-       bool success = false;
-       FILE *subfile = NULL;
-
-       uint8_t suffix_len;
-       READ_BYTE(suffix_len);
-
-       char suffix[256 + 1];
-       READ_BYTES(suffix, suffix_len);
-       suffix[suffix_len] = '\0';
-
-       uint64_t file_len;
-       READ_UINT64(file_len);
-
-       if (dump_stream) {
-               fprintf(
-                       dump_stream,
-                       "Embedded file #%u: %s (%" PRIu64 " bytes)\n",
-                       entry_number,
-                       suffix,
-                       file_len);
-       } else {
-               cc_log(
-                       "Retrieving embedded file #%u %s (%llu bytes)",
-                       entry_number,
-                       suffix,
-                       (unsigned long long)file_len);
-
-               for (uint32_t i = 0; i < list->n_files; i++) {
-                       if (str_eq(suffix, list->files[i].suffix)) {
-                               found = true;
-
-                               cc_log("Copying to %s", list->files[i].path);
-
-                               subfile = fopen(list->files[i].path, "wb");
-                               if (!subfile) {
-                                       cc_log("Failed to open %s for writing", list->files[i].path);
-                                       goto out;
-                               }
-                               char buf[READ_BUFFER_SIZE];
-                               size_t remain = file_len;
-                               while (remain > 0) {
-                                       size_t n = MIN(remain, sizeof(buf));
-                                       READ_BYTES(buf, n);
-                                       if (fwrite(buf, 1, n, subfile) != n) {
-                                               goto out;
-                                       }
-                                       remain -= n;
-                               }
-                               fclose(subfile);
-                               subfile = NULL;
-
-                               break;
-                       }
-               }
-       }
-
-       if (!found) {
-               // Discard the file data.
-               char buf[READ_BUFFER_SIZE];
-               size_t remain = file_len;
-               while (remain > 0) {
-                       size_t n = MIN(remain, sizeof(buf));
-                       READ_BYTES(buf, n);
-                       remain -= n;
-               }
-       }
-
-       success = true;
+  (void)result_path_in_cache;
+  bool found = false;
+  bool success = false;
+  FILE* subfile = NULL;
+
+  uint8_t suffix_len;
+  READ_BYTE(suffix_len);
+
+  char suffix[256 + 1];
+  READ_BYTES(suffix, suffix_len);
+  suffix[suffix_len] = '\0';
+
+  uint64_t file_len;
+  READ_UINT64(file_len);
+
+  if (dump_stream) {
+    fprintf(dump_stream,
+            "Embedded file #%u: %s (%" PRIu64 " bytes)\n",
+            entry_number,
+            suffix,
+            file_len);
+  } else {
+    cc_log("Retrieving embedded file #%u %s (%llu bytes)",
+           entry_number,
+           suffix,
+           (unsigned long long)file_len);
+
+    for (uint32_t i = 0; i < list->n_files; i++) {
+      if (str_eq(suffix, list->files[i].suffix)) {
+        found = true;
+
+        cc_log("Copying to %s", list->files[i].path);
+
+        subfile = fopen(list->files[i].path, "wb");
+        if (!subfile) {
+          cc_log("Failed to open %s for writing", list->files[i].path);
+          goto out;
+        }
+        char buf[READ_BUFFER_SIZE];
+        size_t remain = file_len;
+        while (remain > 0) {
+          size_t n = MIN(remain, sizeof(buf));
+          READ_BYTES(buf, n);
+          if (fwrite(buf, 1, n, subfile) != n) {
+            goto out;
+          }
+          remain -= n;
+        }
+        fclose(subfile);
+        subfile = NULL;
+
+        break;
+      }
+    }
+  }
+
+  if (!found) {
+    // Discard the file data.
+    char buf[READ_BUFFER_SIZE];
+    size_t remain = file_len;
+    while (remain > 0) {
+      size_t n = MIN(remain, sizeof(buf));
+      READ_BYTES(buf, n);
+      remain -= n;
+    }
+  }
+
+  success = true;
 
 out:
-       if (subfile) {
-               fclose(subfile);
-       }
+  if (subfile) {
+    fclose(subfile);
+  }
 
-       return success;
+  return success;
 }
 
-static char *
-get_raw_file_path(const char *result_path_in_cache, uint32_t entry_number)
+static char*
+get_raw_file_path(const charresult_path_in_cache, uint32_t entry_number)
 {
-       return format(
-               "%.*s_%u.raw",
-               (int)strlen(result_path_in_cache) - 7, // .result
-               result_path_in_cache,
-               entry_number);
+  return format("%.*s_%u.raw",
+                (int)strlen(result_path_in_cache) - 7, // .result
+                result_path_in_cache,
+                entry_number);
 }
 
 static bool
-copy_raw_file(const char *source, const char *dest, bool to_cache)
+copy_raw_file(const char* source, const char* dest, bool to_cache)
 {
-       if (conf->file_clone) {
-               cc_log("Cloning %s to %s", source, dest);
-               if (clone_file(source, dest, to_cache)) {
-                       return true;
-               }
-               cc_log("Failed to clone: %s", strerror(errno));
-       }
-       if (conf->hard_link) {
-               x_try_unlink(dest);
-               cc_log("Hard linking %s to %s", source, dest);
-               int ret = link(source, dest);
-               if (ret == 0) {
-                       return true;
-               }
-               cc_log("Failed to hard link: %s", strerror(errno));
-       }
-
-       cc_log("Copying %s to %s", source, dest);
-       return copy_file(source, dest, to_cache);
+  if (conf->file_clone) {
+    cc_log("Cloning %s to %s", source, dest);
+    if (clone_file(source, dest, to_cache)) {
+      return true;
+    }
+    cc_log("Failed to clone: %s", strerror(errno));
+  }
+  if (conf->hard_link) {
+    x_try_unlink(dest);
+    cc_log("Hard linking %s to %s", source, dest);
+    int ret = link(source, dest);
+    if (ret == 0) {
+      return true;
+    }
+    cc_log("Failed to hard link: %s", strerror(errno));
+  }
+
+  cc_log("Copying %s to %s", source, dest);
+  return copy_file(source, dest, to_cache);
 }
 
 static bool
-read_raw_file_entry(
-       struct decompressor *decompressor,
-       struct decompr_state *decompr_state,
-       const char *result_path_in_cache,
-       uint32_t entry_number,
-       const struct result_files *list,
-       FILE *dump_stream)
+read_raw_file_entry(struct decompressor* decompressor,
+                    struct decompr_state* decompr_state,
+                    const char* result_path_in_cache,
+                    uint32_t entry_number,
+                    const struct result_files* list,
+                    FILE* dump_stream)
 {
-       bool success = false;
-       char *raw_path = get_raw_file_path(result_path_in_cache, entry_number);
-
-       uint8_t suffix_len;
-       READ_BYTE(suffix_len);
-
-       char suffix[256 + 1];
-       READ_BYTES(suffix, suffix_len);
-       suffix[suffix_len] = '\0';
-
-       uint64_t file_len;
-       READ_UINT64(file_len);
-
-       if (dump_stream) {
-               fprintf(
-                       dump_stream,
-                       "Raw file #%u: %s (%" PRIu64 " bytes)\n",
-                       entry_number,
-                       suffix,
-                       file_len);
-       } else {
-               cc_log(
-                       "Retrieving raw file #%u %s (%llu bytes)",
-                       entry_number,
-                       suffix,
-                       (unsigned long long)file_len);
-
-               struct stat st;
-               if (x_stat(raw_path, &st) != 0) {
-                       goto out;
-               }
-               if ((uint64_t)st.st_size != file_len) {
-                       cc_log(
-                               "Bad file size of %s (actual %llu bytes, expected %llu bytes)",
-                               raw_path,
-                               (unsigned long long)st.st_size,
-                               (unsigned long long)file_len);
-                       goto out;
-               }
-
-               for (uint32_t i = 0; i < list->n_files; i++) {
-                       if (str_eq(suffix, list->files[i].suffix)) {
-                               if (!copy_raw_file(raw_path, list->files[i].path, false)) {
-                                       goto out;
-                               }
-                               // Update modification timestamp to save the file from LRU cleanup
-                               // (and, if hard-linked, to make the object file newer than the source
-                               // file).
-                               update_mtime(raw_path);
-                               break;
-                       }
-               }
-       }
-
-       success = true;
+  bool success = false;
+  char* raw_path = get_raw_file_path(result_path_in_cache, entry_number);
+
+  uint8_t suffix_len;
+  READ_BYTE(suffix_len);
+
+  char suffix[256 + 1];
+  READ_BYTES(suffix, suffix_len);
+  suffix[suffix_len] = '\0';
+
+  uint64_t file_len;
+  READ_UINT64(file_len);
+
+  if (dump_stream) {
+    fprintf(dump_stream,
+            "Raw file #%u: %s (%" PRIu64 " bytes)\n",
+            entry_number,
+            suffix,
+            file_len);
+  } else {
+    cc_log("Retrieving raw file #%u %s (%llu bytes)",
+           entry_number,
+           suffix,
+           (unsigned long long)file_len);
+
+    struct stat st;
+    if (x_stat(raw_path, &st) != 0) {
+      goto out;
+    }
+    if ((uint64_t)st.st_size != file_len) {
+      cc_log("Bad file size of %s (actual %llu bytes, expected %llu bytes)",
+             raw_path,
+             (unsigned long long)st.st_size,
+             (unsigned long long)file_len);
+      goto out;
+    }
+
+    for (uint32_t i = 0; i < list->n_files; i++) {
+      if (str_eq(suffix, list->files[i].suffix)) {
+        if (!copy_raw_file(raw_path, list->files[i].path, false)) {
+          goto out;
+        }
+        // Update modification timestamp to save the file from LRU cleanup
+        // (and, if hard-linked, to make the object file newer than the source
+        // file).
+        update_mtime(raw_path);
+        break;
+      }
+    }
+  }
+
+  success = true;
 
 out:
-       free(raw_path);
-       return success;
+  free(raw_path);
+  return success;
 }
 
 static bool
-read_result(
-       const char *path,
-       struct result_files *list,
-       FILE *dump_stream,
-       char **errmsg)
+read_result(const char* path,
+            struct result_files* list,
+            FILE* dump_stream,
+            char** errmsg)
 {
-       *errmsg = NULL;
-       bool cache_miss = false;
-       bool success = false;
-       struct decompressor *decompressor = NULL;
-       struct decompr_state *decompr_state = NULL;
-       XXH64_state_t *checksum = XXH64_createState();
-
-       FILE *f = fopen(path, "rb");
-       if (!f) {
-               cache_miss = true;
-               goto out;
-       }
-
-       struct common_header header;
-       if (!common_header_initialize_for_reading(
-             &header,
-             f,
-             RESULT_MAGIC,
-             RESULT_VERSION,
-             &decompressor,
-             &decompr_state,
-             checksum,
-             errmsg)) {
-               goto out;
-       }
-
-       if (dump_stream) {
-               common_header_dump(&header, dump_stream);
-       }
-
-       uint8_t n_entries;
-       READ_BYTE(n_entries);
-
-       uint32_t i;
-       for (i = 0; i < n_entries; i++) {
-               uint8_t marker;
-               READ_BYTE(marker);
-
-               read_entry_fn read_entry;
-
-               switch (marker) {
-               case EMBEDDED_FILE_MARKER:
-                       read_entry = read_embedded_file_entry;
-                       break;
-
-               case RAW_FILE_MARKER:
-                       read_entry = read_raw_file_entry;
-                       break;
-
-               default:
-                       *errmsg = format("Unknown entry type: %u", marker);
-                       goto out;
-               }
-
-               if (!read_entry(decompressor, decompr_state, path, i, list, dump_stream)) {
-                       goto out;
-               }
-       }
-
-       if (i != n_entries) {
-               *errmsg = format("Too few entries (read %u, expected %u)", i, n_entries);
-               goto out;
-       }
-
-       {
-               uint64_t actual_checksum = XXH64_digest(checksum);
-               uint64_t expected_checksum;
-               READ_UINT64(expected_checksum);
-
-               if (actual_checksum == expected_checksum) {
-                       success = true;
-               } else {
-                       *errmsg = format(
-                               "Incorrect checksum (actual %016llx, expected %016llx)",
-                               (unsigned long long)actual_checksum,
-                               (unsigned long long)expected_checksum);
-               }
-       }
+  *errmsg = NULL;
+  bool cache_miss = false;
+  bool success = false;
+  struct decompressor* decompressor = NULL;
+  struct decompr_state* decompr_state = NULL;
+  XXH64_state_t* checksum = XXH64_createState();
+
+  FILE* f = fopen(path, "rb");
+  if (!f) {
+    cache_miss = true;
+    goto out;
+  }
+
+  struct common_header header;
+  if (!common_header_initialize_for_reading(&header,
+                                            f,
+                                            RESULT_MAGIC,
+                                            RESULT_VERSION,
+                                            &decompressor,
+                                            &decompr_state,
+                                            checksum,
+                                            errmsg)) {
+    goto out;
+  }
+
+  if (dump_stream) {
+    common_header_dump(&header, dump_stream);
+  }
+
+  uint8_t n_entries;
+  READ_BYTE(n_entries);
+
+  uint32_t i;
+  for (i = 0; i < n_entries; i++) {
+    uint8_t marker;
+    READ_BYTE(marker);
+
+    read_entry_fn read_entry;
+
+    switch (marker) {
+    case EMBEDDED_FILE_MARKER:
+      read_entry = read_embedded_file_entry;
+      break;
+
+    case RAW_FILE_MARKER:
+      read_entry = read_raw_file_entry;
+      break;
+
+    default:
+      *errmsg = format("Unknown entry type: %u", marker);
+      goto out;
+    }
+
+    if (!read_entry(decompressor, decompr_state, path, i, list, dump_stream)) {
+      goto out;
+    }
+  }
+
+  if (i != n_entries) {
+    *errmsg = format("Too few entries (read %u, expected %u)", i, n_entries);
+    goto out;
+  }
+
+  {
+    uint64_t actual_checksum = XXH64_digest(checksum);
+    uint64_t expected_checksum;
+    READ_UINT64(expected_checksum);
+
+    if (actual_checksum == expected_checksum) {
+      success = true;
+    } else {
+      *errmsg = format("Incorrect checksum (actual %016llx, expected %016llx)",
+                       (unsigned long long)actual_checksum,
+                       (unsigned long long)expected_checksum);
+    }
+  }
 
 out:
-       if (decompressor && !decompressor->free(decompr_state)) {
-               success = false;
-       }
-       if (f) {
-               fclose(f);
-       }
-       if (checksum) {
-               XXH64_freeState(checksum);
-       }
-       if (!success && !cache_miss && !*errmsg) {
-               *errmsg = x_strdup("Corrupt result");
-       }
-       return success;
+  if (decompressor && !decompressor->free(decompr_state)) {
+    success = false;
+  }
+  if (f) {
+    fclose(f);
+  }
+  if (checksum) {
+    XXH64_freeState(checksum);
+  }
+  if (!success && !cache_miss && !*errmsg) {
+    *errmsg = x_strdup("Corrupt result");
+  }
+  return success;
 }
 
-#define WRITE_BYTES(buf, length) \
-       do { \
-               if (!compressor->write(compr_state, buf, length)) { \
-                       goto error; \
-               } \
-       } while (false)
-
-#define WRITE_BYTE(var) \
-       do { \
-               char ch_ = var; \
-               WRITE_BYTES(&ch_, 1); \
-       } while (false)
-
-#define WRITE_UINT64(var) \
-       do { \
-               char buf_[8]; \
-               BYTES_FROM_UINT64(buf_, (var)); \
-               WRITE_BYTES(buf_, sizeof(buf_)); \
-       } while (false)
+#define WRITE_BYTES(buf, length)                                               \
+  do {                                                                         \
+    if (!compressor->write(compr_state, buf, length)) {                        \
+      goto error;                                                              \
+    }                                                                          \
+  } while (false)
+
+#define WRITE_BYTE(var)                                                        \
+  do {                                                                         \
+    char ch_ = var;                                                            \
+    WRITE_BYTES(&ch_, 1);                                                      \
+  } while (false)
+
+#define WRITE_UINT64(var)                                                      \
+  do {                                                                         \
+    char buf_[8];                                                              \
+    BYTES_FROM_UINT64(buf_, (var));                                            \
+    WRITE_BYTES(buf_, sizeof(buf_));                                           \
+  } while (false)
 
 static bool
-write_embedded_file_entry(
-       struct compressor *compressor,
-       struct compr_state *compr_state,
-       const char *result_path_in_cache,
-       uint32_t entry_number,
-       const struct result_file *file)
+write_embedded_file_entry(struct compressor* compressor,
+                          struct compr_state* compr_state,
+                          const char* result_path_in_cache,
+                          uint32_t entry_number,
+                          const struct result_file* file)
 {
-       (void)result_path_in_cache;
-       bool success = false;
-       size_t suffix_len;
-       FILE* f;
-       char buf[READ_BUFFER_SIZE];
-       size_t remain;
-
-       cc_log(
-               "Storing embedded file #%u %s (%llu bytes) from %s",
-               entry_number,
-               file->suffix,
-               (unsigned long long)file->size,
-               file->path);
-
-       WRITE_BYTE(EMBEDDED_FILE_MARKER);
-       suffix_len = strlen(file->suffix);
-       WRITE_BYTE(suffix_len);
-       WRITE_BYTES(file->suffix, suffix_len);
-       WRITE_UINT64(file->size);
-
-       f = fopen(file->path, "rb");
-       if (!f) {
-               cc_log("Failed to open %s for reading", file->path);
-               goto error;
-       }
-       remain = file->size;
-       while (remain > 0) {
-               size_t n = MIN(remain, sizeof(buf));
-               if (fread(buf, 1, n, f) != n) {
-                       goto error;
-               }
-               WRITE_BYTES(buf, n);
-               remain -= n;
-       }
-       fclose(f);
-
-       success = true;
+  (void)result_path_in_cache;
+  bool success = false;
+  size_t suffix_len;
+  FILE* f;
+  char buf[READ_BUFFER_SIZE];
+  size_t remain;
+
+  cc_log("Storing embedded file #%u %s (%llu bytes) from %s",
+         entry_number,
+         file->suffix,
+         (unsigned long long)file->size,
+         file->path);
+
+  WRITE_BYTE(EMBEDDED_FILE_MARKER);
+  suffix_len = strlen(file->suffix);
+  WRITE_BYTE(suffix_len);
+  WRITE_BYTES(file->suffix, suffix_len);
+  WRITE_UINT64(file->size);
+
+  f = fopen(file->path, "rb");
+  if (!f) {
+    cc_log("Failed to open %s for reading", file->path);
+    goto error;
+  }
+  remain = file->size;
+  while (remain > 0) {
+    size_t n = MIN(remain, sizeof(buf));
+    if (fread(buf, 1, n, f) != n) {
+      goto error;
+    }
+    WRITE_BYTES(buf, n);
+    remain -= n;
+  }
+  fclose(f);
+
+  success = true;
 
 error:
-       return success;
+  return success;
 }
 
 static bool
-write_raw_file_entry(
-       struct compressor *compressor,
-       struct compr_state *compr_state,
-       const char *result_path_in_cache,
-       uint32_t entry_number,
-       const struct result_file *file)
+write_raw_file_entry(struct compressor* compressor,
+                     struct compr_state* compr_state,
+                     const char* result_path_in_cache,
+                     uint32_t entry_number,
+                     const struct result_file* file)
 {
-       bool success = false;
-       size_t suffix_len;
-       char* raw_file;
-       struct stat old_stat;
-       bool old_existed;
-       struct stat new_stat;
-       bool new_exists;
-       size_t old_size;
-       size_t new_size;
-
-       cc_log(
-               "Storing raw file #%u %s (%llu bytes) from %s",
-               entry_number,
-               file->suffix,
-               (unsigned long long)file->size,
-               file->path);
-
-       WRITE_BYTE(RAW_FILE_MARKER);
-       suffix_len = strlen(file->suffix);
-       WRITE_BYTE(suffix_len);
-       WRITE_BYTES(file->suffix, suffix_len);
-       WRITE_UINT64(file->size);
-
-       raw_file = get_raw_file_path(result_path_in_cache, entry_number);
-       old_existed = stat(raw_file, &old_stat) == 0;
-       success = copy_raw_file(file->path, raw_file, true);
-       new_exists = stat(raw_file, &new_stat) == 0;
-       free(raw_file);
-
-       old_size = old_existed ? file_size(&old_stat) : 0;
-       new_size = new_exists ? file_size(&new_stat) : 0;
-       stats_update_size(
-               stats_file,
-               new_size - old_size,
-               (new_exists ? 1 : 0) - (old_existed ? 1 : 0));
+  bool success = false;
+  size_t suffix_len;
+  char* raw_file;
+  struct stat old_stat;
+  bool old_existed;
+  struct stat new_stat;
+  bool new_exists;
+  size_t old_size;
+  size_t new_size;
+
+  cc_log("Storing raw file #%u %s (%llu bytes) from %s",
+         entry_number,
+         file->suffix,
+         (unsigned long long)file->size,
+         file->path);
+
+  WRITE_BYTE(RAW_FILE_MARKER);
+  suffix_len = strlen(file->suffix);
+  WRITE_BYTE(suffix_len);
+  WRITE_BYTES(file->suffix, suffix_len);
+  WRITE_UINT64(file->size);
+
+  raw_file = get_raw_file_path(result_path_in_cache, entry_number);
+  old_existed = stat(raw_file, &old_stat) == 0;
+  success = copy_raw_file(file->path, raw_file, true);
+  new_exists = stat(raw_file, &new_stat) == 0;
+  free(raw_file);
+
+  old_size = old_existed ? file_size(&old_stat) : 0;
+  new_size = new_exists ? file_size(&new_stat) : 0;
+  stats_update_size(stats_file,
+                    new_size - old_size,
+                    (new_exists ? 1 : 0) - (old_existed ? 1 : 0));
 
 error:
-       return success;
+  return success;
 }
 
 static bool
-should_store_raw_file(const char *suffix)
+should_store_raw_file(const charsuffix)
 {
-       if (!conf->file_clone && !conf->hard_link) {
-               return false;
-       }
-
-       // - Don't store stderr outputs as raw files since they:
-       //   1. Never are large.
-       //   2. Will end up in a temporary file anyway.
-       //
-       // - Don't store .d files since they:
-       //   1. Never are large.
-       //   2. Compress well.
-       //   3. Cause trouble for automake if hard-linked (see ccache issue 378).
-       //
-       // Note that .d files can't be stored as raw files for the file_clone case
-       // since the hard link mode happily will try to use them if they exist. This
-       // could be fixed by letting read_raw_file_entry refuse to hard link .d
-       // files, but it's easier to simply always store them embedded. This will
-       // also save i-nodes in the cache.
-       return !str_eq(suffix, RESULT_STDERR_NAME) && !str_eq(suffix, ".d");
+  if (!conf->file_clone && !conf->hard_link) {
+    return false;
+  }
+
+  // - Don't store stderr outputs as raw files since they:
+  //   1. Never are large.
+  //   2. Will end up in a temporary file anyway.
+  //
+  // - Don't store .d files since they:
+  //   1. Never are large.
+  //   2. Compress well.
+  //   3. Cause trouble for automake if hard-linked (see ccache issue 378).
+  //
+  // Note that .d files can't be stored as raw files for the file_clone case
+  // since the hard link mode happily will try to use them if they exist. This
+  // could be fixed by letting read_raw_file_entry refuse to hard link .d
+  // files, but it's easier to simply always store them embedded. This will
+  // also save i-nodes in the cache.
+  return !str_eq(suffix, RESULT_STDERR_NAME) && !str_eq(suffix, ".d");
 }
 
 static bool
-write_result(
-       const struct result_files *list,
-       struct compressor *compressor,
-       struct compr_state *compr_state,
-       XXH64_state_t *checksum,
-       const char *result_path_in_cache)
+write_result(const struct result_files* list,
+             struct compressor* compressor,
+             struct compr_state* compr_state,
+             XXH64_state_t* checksum,
+             const char* result_path_in_cache)
 {
-       WRITE_BYTE(list->n_files);
+  WRITE_BYTE(list->n_files);
 
-       for (uint32_t i = 0; i < list->n_files; i++) {
-               write_entry_fn write_entry =
-                       should_store_raw_file(list->files[i].suffix)
-                       ? write_raw_file_entry
-                       : write_embedded_file_entry;
-               if (!write_entry(
-                     compressor, compr_state, result_path_in_cache, i, &list->files[i])) {
-                       goto error;
-               }
-       }
+  for (uint32_t i = 0; i < list->n_files; i++) {
+    write_entry_fn write_entry = should_store_raw_file(list->files[i].suffix)
+                                   ? write_raw_file_entry
+                                   : write_embedded_file_entry;
+    if (!write_entry(
+          compressor, compr_state, result_path_in_cache, i, &list->files[i])) {
+      goto error;
+    }
+  }
 
-       WRITE_UINT64(XXH64_digest(checksum));
+  WRITE_UINT64(XXH64_digest(checksum));
 
-       return true;
+  return true;
 
 error:
-       cc_log("Error writing to result file");
-       return false;
+  cc_log("Error writing to result file");
+  return false;
 }
 
-bool result_get(const char *path, struct result_files *list)
+bool
+result_get(const char* path, struct result_files* list)
 {
-       cc_log("Getting result %s", path);
-
-       char *errmsg;
-       bool success = read_result(path, list, NULL, &errmsg);
-       if (success) {
-               // Update modification timestamp to save files from LRU cleanup.
-               update_mtime(path);
-       } else if (errmsg) {
-               cc_log("Error: %s", errmsg);
-               free(errmsg);
-       } else {
-               cc_log("No such result file");
-       }
-       return success;
+  cc_log("Getting result %s", path);
+
+  char* errmsg;
+  bool success = read_result(path, list, NULL, &errmsg);
+  if (success) {
+    // Update modification timestamp to save files from LRU cleanup.
+    update_mtime(path);
+  } else if (errmsg) {
+    cc_log("Error: %s", errmsg);
+    free(errmsg);
+  } else {
+    cc_log("No such result file");
+  }
+  return success;
 }
 
-bool result_put(const char *path, struct result_files *list)
+bool
+result_put(const char* path, struct result_files* list)
 {
-       bool ret = false;
-       XXH64_state_t *checksum = XXH64_createState();
-       bool ok;
-       uint64_t content_size;
-
-       char *tmp_file = format("%s.tmp", path);
-       int fd = create_tmp_fd(&tmp_file);
-       FILE *f = fdopen(fd, "wb");
-       if (!f) {
-               cc_log("Failed to fdopen %s", tmp_file);
-               goto out;
-       }
-
-       content_size = COMMON_HEADER_SIZE;
-       content_size += 1; // n_entries
-       for (uint32_t i = 0; i < list->n_files; i++) {
-               content_size += 1; // embedded_file_marker
-               content_size += 1; // suffix_len
-               content_size += strlen(list->files[i].suffix); // suffix
-               content_size += 8; // data_len
-               content_size += list->files[i].size; // data
-       }
-       content_size += 8; // checksum
-
-       struct common_header header;
-       struct compressor *compressor;
-       struct compr_state *compr_state;
-       if (!common_header_initialize_for_writing(
-             &header,
-             f,
-             RESULT_MAGIC,
-             RESULT_VERSION,
-             compression_type_from_config(),
-             compression_level_from_config(),
-             content_size,
-             checksum,
-             &compressor,
-             &compr_state)) {
-               goto out;
-       }
-
-       ok = write_result(list, compressor, compr_state, checksum, path)
-            && compressor->free(compr_state);
-       if (!ok) {
-               cc_log("Failed to write result file");
-               goto out;
-       }
-
-       fclose(f);
-       f = NULL;
-       if (x_rename(tmp_file, path) == 0) {
-               ret = true;
-       } else {
-               cc_log("Failed to rename %s to %s", tmp_file, path);
-       }
+  bool ret = false;
+  XXH64_state_t* checksum = XXH64_createState();
+  bool ok;
+  uint64_t content_size;
+
+  char* tmp_file = format("%s.tmp", path);
+  int fd = create_tmp_fd(&tmp_file);
+  FILE* f = fdopen(fd, "wb");
+  if (!f) {
+    cc_log("Failed to fdopen %s", tmp_file);
+    goto out;
+  }
+
+  content_size = COMMON_HEADER_SIZE;
+  content_size += 1; // n_entries
+  for (uint32_t i = 0; i < list->n_files; i++) {
+    content_size += 1;                             // embedded_file_marker
+    content_size += 1;                             // suffix_len
+    content_size += strlen(list->files[i].suffix); // suffix
+    content_size += 8;                             // data_len
+    content_size += list->files[i].size;           // data
+  }
+  content_size += 8; // checksum
+
+  struct common_header header;
+  struct compressor* compressor;
+  struct compr_state* compr_state;
+  if (!common_header_initialize_for_writing(&header,
+                                            f,
+                                            RESULT_MAGIC,
+                                            RESULT_VERSION,
+                                            compression_type_from_config(),
+                                            compression_level_from_config(),
+                                            content_size,
+                                            checksum,
+                                            &compressor,
+                                            &compr_state)) {
+    goto out;
+  }
+
+  ok = write_result(list, compressor, compr_state, checksum, path)
+       && compressor->free(compr_state);
+  if (!ok) {
+    cc_log("Failed to write result file");
+    goto out;
+  }
+
+  fclose(f);
+  f = NULL;
+  if (x_rename(tmp_file, path) == 0) {
+    ret = true;
+  } else {
+    cc_log("Failed to rename %s to %s", tmp_file, path);
+  }
 
 out:
-       free(tmp_file);
-       if (f) {
-               fclose(f);
-       }
-       if (checksum) {
-               XXH64_freeState(checksum);
-       }
-       return ret;
+  free(tmp_file);
+  if (f) {
+    fclose(f);
+  }
+  if (checksum) {
+    XXH64_freeState(checksum);
+  }
+  return ret;
 }
 
 bool
-result_dump(const char *path, FILE *stream)
+result_dump(const char* path, FILE* stream)
 {
-       assert(stream);
-
-       char *errmsg;
-       bool success = read_result(path, NULL, stream, &errmsg);
-       if (errmsg) {
-               fprintf(stream, "Error: %s\n", errmsg);
-               free(errmsg);
-       }
-       return success;
+  assert(stream);
+
+  char* errmsg;
+  bool success = read_result(path, NULL, stream, &errmsg);
+  if (errmsg) {
+    fprintf(stream, "Error: %s\n", errmsg);
+    free(errmsg);
+  }
+  return success;
 }
index 20212b60cf638611bf6652bba67f5480d688534b..e9b0700d82964febb8e47716bcd4b7b546828292 100644 (file)
@@ -26,11 +26,11 @@ extern const char RESULT_MAGIC[4];
 
 struct result_files;
 
-struct result_files *result_files_init(void);
-void result_files_add(
-       struct result_files *c, const char *path, const char *suffix);
-void result_files_free(struct result_files *c);
+struct result_filesresult_files_init(void);
+void
+result_files_add(struct result_files* c, const char* path, const char* suffix);
+void result_files_free(struct result_filesc);
 
-bool result_get(const char *path, struct result_files *list);
-bool result_put(const char *path, struct result_files *list);
-bool result_dump(const char *path, FILE *stream);
+bool result_get(const char* path, struct result_files* list);
+bool result_put(const char* path, struct result_files* list);
+bool result_dump(const char* path, FILE* stream);
index 033b458e2a70c2e99601126fb86ce8063b847b6f..0a6b9c604aa3083644c3ca12feddfe2176407779 100644 (file)
 #include "ccache.hpp"
 #include "hashutil.hpp"
 
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
-extern char *stats_file;
-extern struct conf *conf;
+extern charstats_file;
+extern struct confconf;
 extern unsigned lock_staleness_limit;
-extern char *primary_config_path;
-extern char *secondary_config_path;
+extern charprimary_config_path;
+extern charsecondary_config_path;
 
-static struct counters *counter_updates;
+static struct counterscounter_updates;
 
 #define FLAG_NOZERO 1 // don't zero with the -z option
 #define FLAG_ALWAYS 2 // always show, even if zero
-#define FLAG_NEVER 4 // never show
+#define FLAG_NEVER 4  // never show
 
 // Returns a formatted version of a statistics value, or NULL if the statistics
 // line shouldn't be printed. Caller frees.
-typedef char *(*format_fn)(uint64_t value);
+typedef char(*format_fn)(uint64_t value);
 
-static char *format_size_times_1024(uint64_t size);
-static char *format_timestamp(uint64_t timestamp);
-static void stats_flush_to_file(const char *sfile, struct counters *updates);
+static charformat_size_times_1024(uint64_t size);
+static charformat_timestamp(uint64_t timestamp);
+static void stats_flush_to_file(const char* sfile, struct counters* updates);
 
 // Statistics fields in display order.
-static struct {
-       enum stats stat;
-       const char *id; // for --print-stats
-       const char *message; // for --show-stats
-       format_fn format; // NULL -> use plain integer format
-       unsigned flags;
+static struct
+{
+  enum stats stat;
+  const char* id;      // for --print-stats
+  const char* message; // for --show-stats
+  format_fn format;    // NULL -> use plain integer format
+  unsigned flags;
 } stats_info[] = {
-       {
-               STATS_ZEROTIMESTAMP,
-               "stats_zeroed_timestamp",
-               "stats zeroed",
-               format_timestamp,
-               FLAG_ALWAYS
-       },
-       {
-               STATS_CACHEHIT_DIR,
-               "direct_cache_hit",
-               "cache hit (direct)",
-               NULL,
-               FLAG_ALWAYS
-       },
-       {
-               STATS_CACHEHIT_CPP,
-               "preprocessed_cache_hit",
-               "cache hit (preprocessed)",
-               NULL,
-               FLAG_ALWAYS
-       },
-       {
-               STATS_TOCACHE,
-               "cache_miss",
-               "cache miss",
-               NULL,
-               FLAG_ALWAYS
-       },
-       {
-               STATS_LINK,
-               "called_for_link",
-               "called for link",
-               NULL,
-               0
-       },
-       {
-               STATS_PREPROCESSING,
-               "called_for_preprocessing",
-               "called for preprocessing",
-               NULL,
-               0
-       },
-       {
-               STATS_MULTIPLE,
-               "multiple_source_files",
-               "multiple source files",
-               NULL,
-               0
-       },
-       {
-               STATS_STDOUT,
-               "compiler_produced_stdout",
-               "compiler produced stdout",
-               NULL,
-               0
-       },
-       {
-               STATS_NOOUTPUT,
-               "compiler_produced_no_output",
-               "compiler produced no output",
-               NULL,
-               0
-       },
-       {
-               STATS_EMPTYOUTPUT,
-               "compiler_produced_empty_output",
-               "compiler produced empty output",
-               NULL,
-               0
-       },
-       {
-               STATS_STATUS,
-               "compile_failed",
-               "compile failed",
-               NULL,
-               0
-       },
-       {
-               STATS_ERROR,
-               "internal_error",
-               "ccache internal error",
-               NULL,
-               0
-       },
-       {
-               STATS_PREPROCESSOR,
-               "preprocessor_error",
-               "preprocessor error",
-               NULL,
-               0
-       },
-       {
-               STATS_CANTUSEPCH,
-               "could_not_use_precompiled_header",
-               "can't use precompiled header",
-               NULL,
-               0
-       },
-       {
-               STATS_COMPILER,
-               "could_not_find_compiler",
-               "couldn't find the compiler",
-               NULL,
-               0
-       },
-       {
-               STATS_MISSING,
-               "missing_cache_file",
-               "cache file missing",
-               NULL,
-               0
-       },
-       {
-               STATS_ARGS,
-               "bad_compiler_arguments",
-               "bad compiler arguments",
-               NULL,
-               0
-       },
-       {
-               STATS_SOURCELANG,
-               "unsupported_source_language",
-               "unsupported source language",
-               NULL,
-               0
-       },
-       {
-               STATS_COMPCHECK,
-               "compiler_check_failed",
-               "compiler check failed",
-               NULL,
-               0
-       },
-       {
-               STATS_CONFTEST,
-               "autoconf_test",
-               "autoconf compile/link",
-               NULL,
-               0
-       },
-       {
-               STATS_UNSUPPORTED_OPTION,
-               "unsupported_compiler_option",
-               "unsupported compiler option",
-               NULL,
-               0
-       },
-       {
-               STATS_UNSUPPORTED_DIRECTIVE,
-               "unsupported_code_directive",
-               "unsupported code directive",
-               NULL,
-               0
-       },
-       {
-               STATS_OUTSTDOUT,
-               "output_to_stdout",
-               "output to stdout",
-               NULL,
-               0
-       },
-       {
-               STATS_BADOUTPUTFILE,
-               "bad_output_file",
-               "could not write to output file",
-               NULL,
-               0
-       },
-       {
-               STATS_NOINPUT,
-               "no_input_file",
-               "no input file",
-               NULL,
-               0
-       },
-       {
-               STATS_BADEXTRAFILE,
-               "error_hashing_extra_file",
-               "error hashing extra file",
-               NULL,
-               0
-       },
-       {
-               STATS_NUMCLEANUPS,
-               "cleanups_performed",
-               "cleanups performed",
-               NULL,
-               FLAG_ALWAYS
-       },
-       {
-               STATS_NUMFILES,
-               "files_in_cache",
-               "files in cache",
-               NULL,
-               FLAG_NOZERO|FLAG_ALWAYS
-       },
-       {
-               STATS_TOTALSIZE,
-               "cache_size_kibibyte",
-               "cache size",
-               format_size_times_1024,
-               FLAG_NOZERO|FLAG_ALWAYS
-       },
-       {
-               STATS_OBSOLETE_MAXFILES,
-               "OBSOLETE",
-               "OBSOLETE",
-               NULL,
-               FLAG_NOZERO|FLAG_NEVER
-       },
-       {
-               STATS_OBSOLETE_MAXSIZE,
-               "OBSOLETE",
-               "OBSOLETE",
-               NULL,
-               FLAG_NOZERO|FLAG_NEVER
-       },
-       {
-               STATS_NONE,
-               NULL,
-               NULL,
-               NULL,
-               0
-       }
-};
-
-static char *
+  {STATS_ZEROTIMESTAMP,
+   "stats_zeroed_timestamp",
+   "stats zeroed",
+   format_timestamp,
+   FLAG_ALWAYS},
+  {STATS_CACHEHIT_DIR,
+   "direct_cache_hit",
+   "cache hit (direct)",
+   NULL,
+   FLAG_ALWAYS},
+  {STATS_CACHEHIT_CPP,
+   "preprocessed_cache_hit",
+   "cache hit (preprocessed)",
+   NULL,
+   FLAG_ALWAYS},
+  {STATS_TOCACHE, "cache_miss", "cache miss", NULL, FLAG_ALWAYS},
+  {STATS_LINK, "called_for_link", "called for link", NULL, 0},
+  {STATS_PREPROCESSING,
+   "called_for_preprocessing",
+   "called for preprocessing",
+   NULL,
+   0},
+  {STATS_MULTIPLE, "multiple_source_files", "multiple source files", NULL, 0},
+  {STATS_STDOUT,
+   "compiler_produced_stdout",
+   "compiler produced stdout",
+   NULL,
+   0},
+  {STATS_NOOUTPUT,
+   "compiler_produced_no_output",
+   "compiler produced no output",
+   NULL,
+   0},
+  {STATS_EMPTYOUTPUT,
+   "compiler_produced_empty_output",
+   "compiler produced empty output",
+   NULL,
+   0},
+  {STATS_STATUS, "compile_failed", "compile failed", NULL, 0},
+  {STATS_ERROR, "internal_error", "ccache internal error", NULL, 0},
+  {STATS_PREPROCESSOR, "preprocessor_error", "preprocessor error", NULL, 0},
+  {STATS_CANTUSEPCH,
+   "could_not_use_precompiled_header",
+   "can't use precompiled header",
+   NULL,
+   0},
+  {STATS_COMPILER,
+   "could_not_find_compiler",
+   "couldn't find the compiler",
+   NULL,
+   0},
+  {STATS_MISSING, "missing_cache_file", "cache file missing", NULL, 0},
+  {STATS_ARGS, "bad_compiler_arguments", "bad compiler arguments", NULL, 0},
+  {STATS_SOURCELANG,
+   "unsupported_source_language",
+   "unsupported source language",
+   NULL,
+   0},
+  {STATS_COMPCHECK, "compiler_check_failed", "compiler check failed", NULL, 0},
+  {STATS_CONFTEST, "autoconf_test", "autoconf compile/link", NULL, 0},
+  {STATS_UNSUPPORTED_OPTION,
+   "unsupported_compiler_option",
+   "unsupported compiler option",
+   NULL,
+   0},
+  {STATS_UNSUPPORTED_DIRECTIVE,
+   "unsupported_code_directive",
+   "unsupported code directive",
+   NULL,
+   0},
+  {STATS_OUTSTDOUT, "output_to_stdout", "output to stdout", NULL, 0},
+  {STATS_BADOUTPUTFILE,
+   "bad_output_file",
+   "could not write to output file",
+   NULL,
+   0},
+  {STATS_NOINPUT, "no_input_file", "no input file", NULL, 0},
+  {STATS_BADEXTRAFILE,
+   "error_hashing_extra_file",
+   "error hashing extra file",
+   NULL,
+   0},
+  {STATS_NUMCLEANUPS,
+   "cleanups_performed",
+   "cleanups performed",
+   NULL,
+   FLAG_ALWAYS},
+  {STATS_NUMFILES,
+   "files_in_cache",
+   "files in cache",
+   NULL,
+   FLAG_NOZERO | FLAG_ALWAYS},
+  {STATS_TOTALSIZE,
+   "cache_size_kibibyte",
+   "cache size",
+   format_size_times_1024,
+   FLAG_NOZERO | FLAG_ALWAYS},
+  {STATS_OBSOLETE_MAXFILES,
+   "OBSOLETE",
+   "OBSOLETE",
+   NULL,
+   FLAG_NOZERO | FLAG_NEVER},
+  {STATS_OBSOLETE_MAXSIZE,
+   "OBSOLETE",
+   "OBSOLETE",
+   NULL,
+   FLAG_NOZERO | FLAG_NEVER},
+  {STATS_NONE, NULL, NULL, NULL, 0}};
+
+static char*
 format_size(uint64_t size)
 {
-       char *s = format_human_readable_size(size);
-       reformat(&s, "%11s", s);
-       return s;
+  char* s = format_human_readable_size(size);
+  reformat(&s, "%11s", s);
+  return s;
 }
 
-static char *
+static char*
 format_size_times_1024(uint64_t size)
 {
-       return format_size(size * 1024);
+  return format_size(size * 1024);
 }
 
-static char *
+static char*
 format_timestamp(uint64_t timestamp)
 {
-       if (timestamp > 0) {
-               struct tm tm;
-               localtime_r((time_t *)&timestamp, &tm);
-               char buffer[100];
-               strftime(buffer, sizeof(buffer), "%c", &tm);
-               return format("    %s", buffer);
-       } else {
-               return NULL;
-       }
+  if (timestamp > 0) {
+    struct tm tm;
+    localtime_r((time_t*)&timestamp, &tm);
+    char buffer[100];
+    strftime(buffer, sizeof(buffer), "%c", &tm);
+    return format("    %s", buffer);
+  } else {
+    return NULL;
+  }
 }
 
 // Parse a stats file from a buffer, adding to the counters.
 static void
-parse_stats(struct counters *counters, const char *buf)
+parse_stats(struct counters* counters, const char* buf)
 {
-       size_t i = 0;
-       const char *p = buf;
-       while (true) {
-               char *p2;
-               long val = strtol(p, &p2, 10);
-               if (p2 == p) {
-                       break;
-               }
-               if (counters->size < i + 1) {
-                       counters_resize(counters, i + 1);
-               }
-               counters->data[i] += val;
-               i++;
-               p = p2;
-       }
+  size_t i = 0;
+  const char* p = buf;
+  while (true) {
+    char* p2;
+    long val = strtol(p, &p2, 10);
+    if (p2 == p) {
+      break;
+    }
+    if (counters->size < i + 1) {
+      counters_resize(counters, i + 1);
+    }
+    counters->data[i] += val;
+    i++;
+    p = p2;
+  }
 }
 
 // Write out a stats file.
 void
-stats_write(const char *path, struct counters *counters)
+stats_write(const char* path, struct counters* counters)
 {
-       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);
-               }
-       }
-       fclose(f);
-       x_rename(tmp_file, path);
-       free(tmp_file);
+  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);
+    }
+  }
+  fclose(f);
+  x_rename(tmp_file, path);
+  free(tmp_file);
 }
 
 static void
 init_counter_updates(void)
 {
-       if (!counter_updates) {
-               counter_updates = counters_init(STATS_END);
-       }
+  if (!counter_updates) {
+    counter_updates = counters_init(STATS_END);
+  }
 }
 
 static double
-stats_hit_rate(struct counters *counters)
+stats_hit_rate(struct counterscounters)
 {
-       unsigned direct = counters->data[STATS_CACHEHIT_DIR];
-       unsigned preprocessed = counters->data[STATS_CACHEHIT_CPP];
-       unsigned hit = direct + preprocessed;
-       unsigned miss = counters->data[STATS_TOCACHE];
-       unsigned total = hit + miss;
-       return total > 0 ? (100.0 * hit) / total : 0.0;
+  unsigned direct = counters->data[STATS_CACHEHIT_DIR];
+  unsigned preprocessed = counters->data[STATS_CACHEHIT_CPP];
+  unsigned hit = direct + preprocessed;
+  unsigned miss = counters->data[STATS_TOCACHE];
+  unsigned total = hit + miss;
+  return total > 0 ? (100.0 * hit) / total : 0.0;
 }
 
 static void
-stats_collect(struct counters *counters, time_t *last_updated)
+stats_collect(struct counters* counters, time_t* last_updated)
 {
-       struct stat st;
-       unsigned zero_timestamp = 0;
-
-       *last_updated = 0;
-
-       // Add up the stats in each directory.
-       for (int dir = -1; dir <= 0xF; dir++) {
-               char *fname;
-
-               if (dir == -1) {
-                       fname = format("%s/stats", conf->cache_dir);
-               } else {
-                       fname = format("%s/%1x/stats", conf->cache_dir, dir);
-               }
-
-               counters->data[STATS_ZEROTIMESTAMP] = 0; // Don't add
-               stats_read(fname, counters);
-               zero_timestamp = MAX(counters->data[STATS_ZEROTIMESTAMP], zero_timestamp);
-               if (stat(fname, &st) == 0 && st.st_mtime > *last_updated) {
-                       *last_updated = st.st_mtime;
-               }
-               free(fname);
-       }
-
-       counters->data[STATS_ZEROTIMESTAMP] = zero_timestamp;
+  struct stat st;
+  unsigned zero_timestamp = 0;
+
+  *last_updated = 0;
+
+  // Add up the stats in each directory.
+  for (int dir = -1; dir <= 0xF; dir++) {
+    char* fname;
+
+    if (dir == -1) {
+      fname = format("%s/stats", conf->cache_dir);
+    } else {
+      fname = format("%s/%1x/stats", conf->cache_dir, dir);
+    }
+
+    counters->data[STATS_ZEROTIMESTAMP] = 0; // Don't add
+    stats_read(fname, counters);
+    zero_timestamp = MAX(counters->data[STATS_ZEROTIMESTAMP], zero_timestamp);
+    if (stat(fname, &st) == 0 && st.st_mtime > *last_updated) {
+      *last_updated = st.st_mtime;
+    }
+    free(fname);
+  }
+
+  counters->data[STATS_ZEROTIMESTAMP] = zero_timestamp;
 }
 
 // Record that a number of bytes and files have been added to the cache. Size
 // is in bytes.
 void
-stats_update_size(const char *sfile, int64_t size, int files)
+stats_update_size(const charsfile, int64_t size, int files)
 {
-       struct counters *updates;
-       if (sfile == stats_file) {
-               init_counter_updates();
-               updates = counter_updates;
-       } else {
-               updates = counters_init(STATS_END);
-       }
-       updates->data[STATS_NUMFILES] += files;
-       updates->data[STATS_TOTALSIZE] += size / 1024;
-       if (sfile != stats_file) {
-               stats_flush_to_file(sfile, updates);
-               counters_free(updates);
-       }
+  struct counters* updates;
+  if (sfile == stats_file) {
+    init_counter_updates();
+    updates = counter_updates;
+  } else {
+    updates = counters_init(STATS_END);
+  }
+  updates->data[STATS_NUMFILES] += files;
+  updates->data[STATS_TOTALSIZE] += size / 1024;
+  if (sfile != stats_file) {
+    stats_flush_to_file(sfile, updates);
+    counters_free(updates);
+  }
 }
 
 // Read in the stats from one directory and add to the counters.
 void
-stats_read(const char *sfile, struct counters *counters)
+stats_read(const char* sfile, struct counters* counters)
 {
-       char *data = read_text_file(sfile, 1024);
-       if (data) {
-               parse_stats(counters, data);
-       }
-       free(data);
+  char* data = read_text_file(sfile, 1024);
+  if (data) {
+    parse_stats(counters, data);
+  }
+  free(data);
 }
 
 // Write counter updates in updates to sfile.
 static void
-stats_flush_to_file(const char *sfile, struct counters *updates)
+stats_flush_to_file(const char* sfile, struct counters* updates)
 {
-       assert(conf);
-
-       if (!conf->stats) {
-               return;
-       }
-
-       if (!updates) {
-               return;
-       }
-
-       bool should_flush = false;
-       for (int i = 0; i < STATS_END; ++i) {
-               if (updates->data[i] > 0) {
-                       should_flush = true;
-                       break;
-               }
-       }
-       if (!should_flush) {
-               return;
-       }
-
-       if (!sfile) {
-               char *stats_dir;
-
-               // A NULL sfile means that we didn't get past calculate_object_hash(), so
-               // we just choose one of stats files in the 16 subdirectories.
-               stats_dir = format("%s/%x", conf->cache_dir, hash_from_int(getpid()) % 16);
-               sfile = format("%s/stats", stats_dir);
-               free(stats_dir);
-       }
-
-       if (!lockfile_acquire(sfile, lock_staleness_limit)) {
-               return;
-       }
-
-       struct counters *counters = counters_init(STATS_END);
-       stats_read(sfile, counters);
-       for (int i = 0; i < STATS_END; ++i) {
-               counters->data[i] += updates->data[i];
-       }
-       stats_write(sfile, counters);
-       lockfile_release(sfile);
-
-       if (!str_eq(conf->log_file, "") || conf->debug) {
-               for (int i = 0; i < STATS_END; ++i) {
-                       if (updates->data[stats_info[i].stat] != 0
-                           && !(stats_info[i].flags & FLAG_NOZERO)) {
-                               cc_log("Result: %s", stats_info[i].message);
-                       }
-               }
-       }
-
-       char *subdir = x_dirname(sfile);
-       bool need_cleanup = false;
-
-       if (conf->max_files != 0
-           && counters->data[STATS_NUMFILES] > conf->max_files / 16) {
-               cc_log("Need to clean up %s since it holds %u files (limit: %u files)",
-                      subdir,
-                      counters->data[STATS_NUMFILES],
-                      conf->max_files / 16);
-               need_cleanup = true;
-       }
-       if (conf->max_size != 0
-           && counters->data[STATS_TOTALSIZE] > conf->max_size / 1024 / 16) {
-               cc_log("Need to clean up %s since it holds %u KiB (limit: %lu KiB)",
-                      subdir,
-                      counters->data[STATS_TOTALSIZE],
-                      (unsigned long)conf->max_size / 1024 / 16);
-               need_cleanup = true;
-       }
-
-       if (need_cleanup) {
-               clean_up_dir(conf, subdir, conf->limit_multiple);
-       }
-
-       free(subdir);
-       counters_free(counters);
+  assert(conf);
+
+  if (!conf->stats) {
+    return;
+  }
+
+  if (!updates) {
+    return;
+  }
+
+  bool should_flush = false;
+  for (int i = 0; i < STATS_END; ++i) {
+    if (updates->data[i] > 0) {
+      should_flush = true;
+      break;
+    }
+  }
+  if (!should_flush) {
+    return;
+  }
+
+  if (!sfile) {
+    char* stats_dir;
+
+    // A NULL sfile means that we didn't get past calculate_object_hash(), so
+    // we just choose one of stats files in the 16 subdirectories.
+    stats_dir = format("%s/%x", conf->cache_dir, hash_from_int(getpid()) % 16);
+    sfile = format("%s/stats", stats_dir);
+    free(stats_dir);
+  }
+
+  if (!lockfile_acquire(sfile, lock_staleness_limit)) {
+    return;
+  }
+
+  struct counters* counters = counters_init(STATS_END);
+  stats_read(sfile, counters);
+  for (int i = 0; i < STATS_END; ++i) {
+    counters->data[i] += updates->data[i];
+  }
+  stats_write(sfile, counters);
+  lockfile_release(sfile);
+
+  if (!str_eq(conf->log_file, "") || conf->debug) {
+    for (int i = 0; i < STATS_END; ++i) {
+      if (updates->data[stats_info[i].stat] != 0
+          && !(stats_info[i].flags & FLAG_NOZERO)) {
+        cc_log("Result: %s", stats_info[i].message);
+      }
+    }
+  }
+
+  char* subdir = x_dirname(sfile);
+  bool need_cleanup = false;
+
+  if (conf->max_files != 0
+      && counters->data[STATS_NUMFILES] > conf->max_files / 16) {
+    cc_log("Need to clean up %s since it holds %u files (limit: %u files)",
+           subdir,
+           counters->data[STATS_NUMFILES],
+           conf->max_files / 16);
+    need_cleanup = true;
+  }
+  if (conf->max_size != 0
+      && counters->data[STATS_TOTALSIZE] > conf->max_size / 1024 / 16) {
+    cc_log("Need to clean up %s since it holds %u KiB (limit: %lu KiB)",
+           subdir,
+           counters->data[STATS_TOTALSIZE],
+           (unsigned long)conf->max_size / 1024 / 16);
+    need_cleanup = true;
+  }
+
+  if (need_cleanup) {
+    clean_up_dir(conf, subdir, conf->limit_multiple);
+  }
+
+  free(subdir);
+  counters_free(counters);
 }
 
 // Write counter updates in counter_updates to disk.
 void
 stats_flush(void)
 {
-       stats_flush_to_file(stats_file, counter_updates);
-       counters_free(counter_updates);
-       counter_updates = NULL;
+  stats_flush_to_file(stats_file, counter_updates);
+  counters_free(counter_updates);
+  counter_updates = NULL;
 }
 
 // Update a normal stat.
 void
 stats_update(enum stats stat)
 {
-       assert(stat > STATS_NONE && stat < STATS_END);
-       init_counter_updates();
-       counter_updates->data[stat]++;
+  assert(stat > STATS_NONE && stat < STATS_END);
+  init_counter_updates();
+  counter_updates->data[stat]++;
 }
 
 // Get the pending update of a counter value.
 unsigned
 stats_get_pending(enum stats stat)
 {
-       init_counter_updates();
-       return counter_updates->data[stat];
+  init_counter_updates();
+  return counter_updates->data[stat];
 }
 
 // Sum and display the total stats for all cache dirs.
 void
 stats_summary(void)
 {
-       assert(conf);
-
-       struct counters *counters = counters_init(STATS_END);
-       time_t last_updated;
-       stats_collect(counters, &last_updated);
-
-       printf("cache directory                     %s\n", conf->cache_dir);
-       printf("primary config                      %s\n",
-              primary_config_path ? primary_config_path : "");
-       printf("secondary config      (readonly)    %s\n",
-              secondary_config_path ? secondary_config_path : "");
-       if (last_updated > 0) {
-               struct tm tm;
-               localtime_r(&last_updated, &tm);
-               char timestamp[100];
-               strftime(timestamp, sizeof(timestamp), "%c", &tm);
-               printf("stats updated                       %s\n", timestamp);
-       }
-
-       // ...and display them.
-       for (int i = 0; stats_info[i].message; i++) {
-               enum stats stat = stats_info[i].stat;
-
-               if (stats_info[i].flags & FLAG_NEVER) {
-                       continue;
-               }
-               if (counters->data[stat] == 0 && !(stats_info[i].flags & FLAG_ALWAYS)) {
-                       continue;
-               }
-
-               char *value;
-               if (stats_info[i].format) {
-                       value = stats_info[i].format(counters->data[stat]);
-               } else {
-                       value = format("%8u", counters->data[stat]);
-               }
-               if (value) {
-                       printf("%-31s %s\n", stats_info[i].message, value);
-                       free(value);
-               }
-
-               if (stat == STATS_TOCACHE) {
-                       double percent = stats_hit_rate(counters);
-                       printf("cache hit rate                    %6.2f %%\n", percent);
-               }
-       }
-
-       if (conf->max_files != 0) {
-               printf("max files                       %8u\n", conf->max_files);
-       }
-       if (conf->max_size != 0) {
-               char *value = format_size(conf->max_size);
-               printf("max cache size                  %s\n", value);
-               free(value);
-       }
-
-       counters_free(counters);
+  assert(conf);
+
+  struct counters* counters = counters_init(STATS_END);
+  time_t last_updated;
+  stats_collect(counters, &last_updated);
+
+  printf("cache directory                     %s\n", conf->cache_dir);
+  printf("primary config                      %s\n",
+         primary_config_path ? primary_config_path : "");
+  printf("secondary config      (readonly)    %s\n",
+         secondary_config_path ? secondary_config_path : "");
+  if (last_updated > 0) {
+    struct tm tm;
+    localtime_r(&last_updated, &tm);
+    char timestamp[100];
+    strftime(timestamp, sizeof(timestamp), "%c", &tm);
+    printf("stats updated                       %s\n", timestamp);
+  }
+
+  // ...and display them.
+  for (int i = 0; stats_info[i].message; i++) {
+    enum stats stat = stats_info[i].stat;
+
+    if (stats_info[i].flags & FLAG_NEVER) {
+      continue;
+    }
+    if (counters->data[stat] == 0 && !(stats_info[i].flags & FLAG_ALWAYS)) {
+      continue;
+    }
+
+    char* value;
+    if (stats_info[i].format) {
+      value = stats_info[i].format(counters->data[stat]);
+    } else {
+      value = format("%8u", counters->data[stat]);
+    }
+    if (value) {
+      printf("%-31s %s\n", stats_info[i].message, value);
+      free(value);
+    }
+
+    if (stat == STATS_TOCACHE) {
+      double percent = stats_hit_rate(counters);
+      printf("cache hit rate                    %6.2f %%\n", percent);
+    }
+  }
+
+  if (conf->max_files != 0) {
+    printf("max files                       %8u\n", conf->max_files);
+  }
+  if (conf->max_size != 0) {
+    char* value = format_size(conf->max_size);
+    printf("max cache size                  %s\n", value);
+    free(value);
+  }
+
+  counters_free(counters);
 }
 
 // Print machine-parsable (tab-separated) statistics counters.
 void
 stats_print(void)
 {
-       assert(conf);
+  assert(conf);
 
-       struct counters *counters = counters_init(STATS_END);
-       time_t last_updated;
-       stats_collect(counters, &last_updated);
+  struct counters* counters = counters_init(STATS_END);
+  time_t last_updated;
+  stats_collect(counters, &last_updated);
 
-       printf("stats_updated_timestamp\t%llu\n", (unsigned long long)last_updated);
+  printf("stats_updated_timestamp\t%llu\n", (unsigned long long)last_updated);
 
-       for (int i = 0; stats_info[i].message; i++) {
-               if (!(stats_info[i].flags & FLAG_NEVER)) {
-                       printf("%s\t%u\n", stats_info[i].id, counters->data[stats_info[i].stat]);
-               }
-       }
+  for (int i = 0; stats_info[i].message; i++) {
+    if (!(stats_info[i].flags & FLAG_NEVER)) {
+      printf("%s\t%u\n", stats_info[i].id, counters->data[stats_info[i].stat]);
+    }
+  }
 
-       counters_free(counters);
+  counters_free(counters);
 }
 
 // Zero all the stats structures.
 void
 stats_zero(void)
 {
-       assert(conf);
-
-       char *fname = format("%s/stats", conf->cache_dir);
-       x_unlink(fname);
-       free(fname);
-
-       time_t timestamp = time(NULL);
-
-       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 (stat(fname, &st) != 0) {
-                       // No point in trying to reset the stats file if it doesn't exist.
-                       free(fname);
-                       continue;
-               }
-               if (lockfile_acquire(fname, lock_staleness_limit)) {
-                       stats_read(fname, counters);
-                       for (unsigned i = 0; stats_info[i].message; i++) {
-                               if (!(stats_info[i].flags & FLAG_NOZERO)) {
-                                       counters->data[stats_info[i].stat] = 0;
-                               }
-                       }
-                       counters->data[STATS_ZEROTIMESTAMP] = timestamp;
-                       stats_write(fname, counters);
-                       lockfile_release(fname);
-               }
-               counters_free(counters);
-               free(fname);
-       }
+  assert(conf);
+
+  char* fname = format("%s/stats", conf->cache_dir);
+  x_unlink(fname);
+  free(fname);
+
+  time_t timestamp = time(NULL);
+
+  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 (stat(fname, &st) != 0) {
+      // No point in trying to reset the stats file if it doesn't exist.
+      free(fname);
+      continue;
+    }
+    if (lockfile_acquire(fname, lock_staleness_limit)) {
+      stats_read(fname, counters);
+      for (unsigned i = 0; stats_info[i].message; i++) {
+        if (!(stats_info[i].flags & FLAG_NOZERO)) {
+          counters->data[stats_info[i].stat] = 0;
+        }
+      }
+      counters->data[STATS_ZEROTIMESTAMP] = timestamp;
+      stats_write(fname, counters);
+      lockfile_release(fname);
+    }
+    counters_free(counters);
+    free(fname);
+  }
 }
 
 // Get the per-directory limits.
 void
-stats_get_obsolete_limits(const char *dir, unsigned *maxfiles,
-                          uint64_t *maxsize)
+stats_get_obsolete_limits(const char* dir,
+                          unsigned* maxfiles,
+                          uint64_t* maxsize)
 {
-       struct counters *counters = counters_init(STATS_END);
-       char *sname = format("%s/stats", dir);
-       stats_read(sname, counters);
-       *maxfiles = counters->data[STATS_OBSOLETE_MAXFILES];
-       *maxsize = (uint64_t)counters->data[STATS_OBSOLETE_MAXSIZE] * 1024;
-       free(sname);
-       counters_free(counters);
+  struct counters* counters = counters_init(STATS_END);
+  char* sname = format("%s/stats", dir);
+  stats_read(sname, counters);
+  *maxfiles = counters->data[STATS_OBSOLETE_MAXFILES];
+  *maxsize = (uint64_t)counters->data[STATS_OBSOLETE_MAXSIZE] * 1024;
+  free(sname);
+  counters_free(counters);
 }
 
 // Set the per-directory sizes.
 void
-stats_set_sizes(const char *dir, unsigned num_files, uint64_t total_size)
+stats_set_sizes(const chardir, unsigned num_files, uint64_t total_size)
 {
-       struct counters *counters = counters_init(STATS_END);
-       char *statsfile = format("%s/stats", dir);
-       if (lockfile_acquire(statsfile, lock_staleness_limit)) {
-               stats_read(statsfile, counters);
-               counters->data[STATS_NUMFILES] = num_files;
-               counters->data[STATS_TOTALSIZE] = total_size / 1024;
-               stats_write(statsfile, counters);
-               lockfile_release(statsfile);
-       }
-       free(statsfile);
-       counters_free(counters);
+  struct counters* counters = counters_init(STATS_END);
+  char* statsfile = format("%s/stats", dir);
+  if (lockfile_acquire(statsfile, lock_staleness_limit)) {
+    stats_read(statsfile, counters);
+    counters->data[STATS_NUMFILES] = num_files;
+    counters->data[STATS_TOTALSIZE] = total_size / 1024;
+    stats_write(statsfile, counters);
+    lockfile_release(statsfile);
+  }
+  free(statsfile);
+  counters_free(counters);
 }
 
 // Count directory cleanup run.
 void
-stats_add_cleanup(const char *dir, unsigned count)
+stats_add_cleanup(const chardir, unsigned count)
 {
-       struct counters *counters = counters_init(STATS_END);
-       char *statsfile = format("%s/stats", dir);
-       if (lockfile_acquire(statsfile, lock_staleness_limit)) {
-               stats_read(statsfile, counters);
-               counters->data[STATS_NUMCLEANUPS] += count;
-               stats_write(statsfile, counters);
-               lockfile_release(statsfile);
-       }
-       free(statsfile);
-       counters_free(counters);
+  struct counters* counters = counters_init(STATS_END);
+  char* statsfile = format("%s/stats", dir);
+  if (lockfile_acquire(statsfile, lock_staleness_limit)) {
+    stats_read(statsfile, counters);
+    counters->data[STATS_NUMCLEANUPS] += count;
+    stats_write(statsfile, counters);
+    lockfile_release(statsfile);
+  }
+  free(statsfile);
+  counters_free(counters);
 }
index 72a98dbf99baf5c0291f71aaf6114a339faf2cee..e95f3e72a2e70c7f0f644d1e4b002baf37717520 100644 (file)
 
 #include <sys/file.h>
 #ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
+#  include <sys/mman.h>
 #endif
 #include <sys/stat.h>
 #include <sys/types.h>
 #ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
+#  include <sys/wait.h>
 #endif
 
 #include <assert.h>
 extern int usleep(useconds_t);
 #endif
 
-extern char **environ;
+extern char** environ;
 
 #ifndef ESTALE
-#define ESTALE -1
+#  define ESTALE -1
 #endif
 
 extern "C" {
 
 #if !HAVE_VSNPRINTF
-  int rpl_vsnprintf(char *, size_t, const char *, va_list);
-  #define vsnprintf rpl_vsnprintf
+int rpl_vsnprintf(char*, size_t, const char*, va_list);
+#  define vsnprintf rpl_vsnprintf
 #endif
 #if !HAVE_SNPRINTF
-  int rpl_snprintf(char *, size_t, const char *, ...);
-  #define snprintf rpl_snprintf
+int rpl_snprintf(char*, size_t, const char*, ...);
+#  define snprintf rpl_snprintf
 #endif
 #if !HAVE_VASPRINTF
-  int rpl_vasprintf(char **, const char *, va_list);
-  #define vasprintf rpl_vasprintf
+int rpl_vasprintf(char**, const char*, va_list);
+#  define vasprintf rpl_vasprintf
 #endif
 #if !HAVE_ASPRINTF
-  int rpl_asprintf(char **, const char *, ...);
-  #define asprintf rpl_asprintf
+int rpl_asprintf(char**, const char*, ...);
+#  define asprintf rpl_asprintf
 #endif
 
 } // extern "C"
index e2f700e2047731459c019d7140c2535c9ed375e8..7a7744edf12e8c6e20bd2ace76970bf37a33eb9b 100644 (file)
 // syntactic errors is important to cope with C/C++ extensions in the local
 // compiler (for example, inline assembly systems).
 
+#include "unify.hpp"
+
 #include "ccache.hpp"
 #include "hash.hpp"
-#include "unify.hpp"
 
 static bool print_unified = true;
 
-static const char *const s_tokens[] = {
-       "...", ">>=", "<<=", "+=", "-=", "*=", "/=", "%=", "&=", "^=",
-       "|=",  ">>",  "<<",  "++", "--", "->", "&&", "||", "<=", ">=",
-       "==",  "!=",  ";",   "{",  "<%", "}",  "%>", ",",  ":",  "=",
-       "(",   ")",   "[",   "<:", "]",  ":>", ".",  "&",  "!",  "~",
-       "-",   "+",   "*",   "/",  "%",  "<",  ">",  "^",  "|",  "?",
-       0
-};
+static const char* const s_tokens[] = {
+  "...", ">>=", "<<=", "+=", "-=", "*=", "/=", "%=", "&=", "^=", "|=",
+  ">>",  "<<",  "++",  "--", "->", "&&", "||", "<=", ">=", "==", "!=",
+  ";",   "{",   "<%",  "}",  "%>", ",",  ":",  "=",  "(",  ")",  "[",
+  "<:",  "]",   ":>",  ".",  "&",  "!",  "~",  "-",  "+",  "*",  "/",
+  "%",   "<",   ">",   "^",  "|",  "?",  0};
 
 #define C_ALPHA 1
 #define C_SPACE 2
 #define C_TOKEN 4
 #define C_QUOTE 8
 #define C_DIGIT 16
-#define C_HEX   32
+#define C_HEX 32
 #define C_FLOAT 64
-#define C_SIGN  128
+#define C_SIGN 128
 
-static struct {
-       unsigned char type;
-       unsigned char num_toks;
-       const char *toks[7];
+static struct
+{
+  unsigned char type;
+  unsigned char num_toks;
+  const char* toks[7];
 } tokens[256];
 
 // Build up the table used by the unifier.
 static void
 build_table(void)
 {
-       static bool done;
-       if (done) {
-               return;
-       }
-       done = true;
+  static bool done;
+  if (done) {
+    return;
+  }
+  done = true;
 
-       memset(tokens, 0, sizeof(tokens));
-       for (unsigned char c = 0; c < 128; c++) {
-               if (isalpha(c) || c == '_') {
-                       tokens[c].type |= C_ALPHA;
-               }
-               if (isdigit(c)) {
-                       tokens[c].type |= C_DIGIT;
-               }
-               if (isspace(c)) {
-                       tokens[c].type |= C_SPACE;
-               }
-               if (isxdigit(c)) {
-                       tokens[c].type |= C_HEX;
-               }
-       }
-       tokens[static_cast<unsigned char>('\'')].type |= C_QUOTE;
-       tokens[static_cast<unsigned char>('"')].type |= C_QUOTE;
-       tokens[static_cast<unsigned char>('l')].type |= C_FLOAT;
-       tokens[static_cast<unsigned char>('L')].type |= C_FLOAT;
-       tokens[static_cast<unsigned char>('f')].type |= C_FLOAT;
-       tokens[static_cast<unsigned char>('F')].type |= C_FLOAT;
-       tokens[static_cast<unsigned char>('U')].type |= C_FLOAT;
-       tokens[static_cast<unsigned char>('u')].type |= C_FLOAT;
+  memset(tokens, 0, sizeof(tokens));
+  for (unsigned char c = 0; c < 128; c++) {
+    if (isalpha(c) || c == '_') {
+      tokens[c].type |= C_ALPHA;
+    }
+    if (isdigit(c)) {
+      tokens[c].type |= C_DIGIT;
+    }
+    if (isspace(c)) {
+      tokens[c].type |= C_SPACE;
+    }
+    if (isxdigit(c)) {
+      tokens[c].type |= C_HEX;
+    }
+  }
+  tokens[static_cast<unsigned char>('\'')].type |= C_QUOTE;
+  tokens[static_cast<unsigned char>('"')].type |= C_QUOTE;
+  tokens[static_cast<unsigned char>('l')].type |= C_FLOAT;
+  tokens[static_cast<unsigned char>('L')].type |= C_FLOAT;
+  tokens[static_cast<unsigned char>('f')].type |= C_FLOAT;
+  tokens[static_cast<unsigned char>('F')].type |= C_FLOAT;
+  tokens[static_cast<unsigned char>('U')].type |= C_FLOAT;
+  tokens[static_cast<unsigned char>('u')].type |= C_FLOAT;
 
-       tokens[static_cast<unsigned char>('-')].type |= C_SIGN;
-       tokens[static_cast<unsigned char>('+')].type |= C_SIGN;
+  tokens[static_cast<unsigned char>('-')].type |= C_SIGN;
+  tokens[static_cast<unsigned char>('+')].type |= C_SIGN;
 
-       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++;
-       }
+  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++;
+  }
 }
 
 // Buffer up characters before hashing them.
 static void
-pushchar(struct hash *hash, unsigned char c)
+pushchar(struct hashhash, unsigned char c)
 {
-       static unsigned char buf[64];
-       static size_t len;
+  static unsigned char buf[64];
+  static size_t len;
 
-       if (c == 0) {
-               if (len > 0) {
-                       hash_buffer(hash, (char *)buf, len);
-                       if (print_unified) {
-                               printf("%.*s", (int) len, buf);
-                       }
-                       len = 0;
-               }
-               return;
-       }
+  if (c == 0) {
+    if (len > 0) {
+      hash_buffer(hash, (char*)buf, len);
+      if (print_unified) {
+        printf("%.*s", (int)len, buf);
+      }
+      len = 0;
+    }
+    return;
+  }
 
-       buf[len++] = c;
-       if (len == 64) {
-               hash_buffer(hash, (char *)buf, len);
-               if (print_unified) {
-                       printf("%.*s", (int) len, buf);
-               }
-               len = 0;
-       }
+  buf[len++] = c;
+  if (len == 64) {
+    hash_buffer(hash, (char*)buf, len);
+    if (print_unified) {
+      printf("%.*s", (int)len, buf);
+    }
+    len = 0;
+  }
 }
 
 // Hash some C/C++ code after unifying.
 static void
-unify(struct hash *hash, unsigned char *p, size_t size)
+unify(struct hash* hash, unsigned char* p, size_t size)
 {
-       build_table();
+  build_table();
 
-       for (size_t ofs = 0; ofs < size;) {
-               if (p[ofs] == '#') {
-                       if ((size-ofs) > 2 && p[ofs+1] == ' ' && isdigit(p[ofs+2])) {
-                               do {
-                                       ofs++;
-                               } while (ofs < size && p[ofs] != '\n');
-                               ofs++;
-                       } else {
-                               do {
-                                       pushchar(hash, p[ofs]);
-                                       ofs++;
-                               } while (ofs < size && p[ofs] != '\n');
-                               pushchar(hash, '\n');
-                               ofs++;
-                       }
-                       continue;
-               }
+  for (size_t ofs = 0; ofs < size;) {
+    if (p[ofs] == '#') {
+      if ((size - ofs) > 2 && p[ofs + 1] == ' ' && isdigit(p[ofs + 2])) {
+        do {
+          ofs++;
+        } while (ofs < size && p[ofs] != '\n');
+        ofs++;
+      } else {
+        do {
+          pushchar(hash, p[ofs]);
+          ofs++;
+        } while (ofs < size && p[ofs] != '\n');
+        pushchar(hash, '\n');
+        ofs++;
+      }
+      continue;
+    }
 
-               if (tokens[p[ofs]].type & C_ALPHA) {
-                       do {
-                               pushchar(hash, p[ofs]);
-                               ofs++;
-                       } while (ofs < size && (tokens[p[ofs]].type & (C_ALPHA|C_DIGIT)));
-                       pushchar(hash, '\n');
-                       continue;
-               }
+    if (tokens[p[ofs]].type & C_ALPHA) {
+      do {
+        pushchar(hash, p[ofs]);
+        ofs++;
+      } while (ofs < size && (tokens[p[ofs]].type & (C_ALPHA | C_DIGIT)));
+      pushchar(hash, '\n');
+      continue;
+    }
 
-               if (tokens[p[ofs]].type & C_DIGIT) {
-                       do {
-                               pushchar(hash, p[ofs]);
-                               ofs++;
-                       } while (ofs < size &&
-                                ((tokens[p[ofs]].type & C_DIGIT) || p[ofs] == '.'));
-                       if (ofs < size && (p[ofs] == 'x' || p[ofs] == 'X')) {
-                               do {
-                                       pushchar(hash, p[ofs]);
-                                       ofs++;
-                               } while (ofs < size && (tokens[p[ofs]].type & C_HEX));
-                       }
-                       if (ofs < size && (p[ofs] == 'E' || p[ofs] == 'e')) {
-                               pushchar(hash, p[ofs]);
-                               ofs++;
-                               while (ofs < size && (tokens[p[ofs]].type & (C_DIGIT|C_SIGN))) {
-                                       pushchar(hash, p[ofs]);
-                                       ofs++;
-                               }
-                       }
-                       while (ofs < size && (tokens[p[ofs]].type & C_FLOAT)) {
-                               pushchar(hash, p[ofs]);
-                               ofs++;
-                       }
-                       pushchar(hash, '\n');
-                       continue;
-               }
+    if (tokens[p[ofs]].type & C_DIGIT) {
+      do {
+        pushchar(hash, p[ofs]);
+        ofs++;
+      } while (ofs < size
+               && ((tokens[p[ofs]].type & C_DIGIT) || p[ofs] == '.'));
+      if (ofs < size && (p[ofs] == 'x' || p[ofs] == 'X')) {
+        do {
+          pushchar(hash, p[ofs]);
+          ofs++;
+        } while (ofs < size && (tokens[p[ofs]].type & C_HEX));
+      }
+      if (ofs < size && (p[ofs] == 'E' || p[ofs] == 'e')) {
+        pushchar(hash, p[ofs]);
+        ofs++;
+        while (ofs < size && (tokens[p[ofs]].type & (C_DIGIT | C_SIGN))) {
+          pushchar(hash, p[ofs]);
+          ofs++;
+        }
+      }
+      while (ofs < size && (tokens[p[ofs]].type & C_FLOAT)) {
+        pushchar(hash, p[ofs]);
+        ofs++;
+      }
+      pushchar(hash, '\n');
+      continue;
+    }
 
-               if (tokens[p[ofs]].type & C_SPACE) {
-                       do {
-                               ofs++;
-                       } while (ofs < size && (tokens[p[ofs]].type & C_SPACE));
-                       continue;
-               }
+    if (tokens[p[ofs]].type & C_SPACE) {
+      do {
+        ofs++;
+      } while (ofs < size && (tokens[p[ofs]].type & C_SPACE));
+      continue;
+    }
 
-               if (tokens[p[ofs]].type & C_QUOTE) {
-                       unsigned char q = p[ofs];
-                       pushchar(hash, p[ofs]);
-                       do {
-                               ofs++;
-                               while (ofs < size-1 && p[ofs] == '\\') {
-                                       pushchar(hash, p[ofs]);
-                                       pushchar(hash, p[ofs+1]);
-                                       ofs += 2;
-                               }
-                               pushchar(hash, p[ofs]);
-                       } while (ofs < size && p[ofs] != q);
-                       pushchar(hash, '\n');
-                       ofs++;
-                       continue;
-               }
+    if (tokens[p[ofs]].type & C_QUOTE) {
+      unsigned char q = p[ofs];
+      pushchar(hash, p[ofs]);
+      do {
+        ofs++;
+        while (ofs < size - 1 && p[ofs] == '\\') {
+          pushchar(hash, p[ofs]);
+          pushchar(hash, p[ofs + 1]);
+          ofs += 2;
+        }
+        pushchar(hash, p[ofs]);
+      } while (ofs < size && p[ofs] != q);
+      pushchar(hash, '\n');
+      ofs++;
+      continue;
+    }
 
-               if (tokens[p[ofs]].type & C_TOKEN) {
-                       unsigned char q = p[ofs];
-                       int i;
-                       for (i = 0; i < tokens[q].num_toks; i++) {
-                               const unsigned char *s = (const unsigned char *)tokens[q].toks[i];
-                               int len = strlen((const char *)s);
-                               if (size >= ofs+len && memcmp(&p[ofs], s, len) == 0) {
-                                       int j;
-                                       for (j = 0; s[j]; j++) {
-                                               pushchar(hash, s[j]);
-                                               ofs++;
-                                       }
-                                       pushchar(hash, '\n');
-                                       break;
-                               }
-                       }
-                       if (i < tokens[q].num_toks) {
-                               continue;
-                       }
-               }
+    if (tokens[p[ofs]].type & C_TOKEN) {
+      unsigned char q = p[ofs];
+      int i;
+      for (i = 0; i < tokens[q].num_toks; i++) {
+        const unsigned char* s = (const unsigned char*)tokens[q].toks[i];
+        int len = strlen((const char*)s);
+        if (size >= ofs + len && memcmp(&p[ofs], s, len) == 0) {
+          int j;
+          for (j = 0; s[j]; j++) {
+            pushchar(hash, s[j]);
+            ofs++;
+          }
+          pushchar(hash, '\n');
+          break;
+        }
+      }
+      if (i < tokens[q].num_toks) {
+        continue;
+      }
+    }
 
-               pushchar(hash, p[ofs]);
-               pushchar(hash, '\n');
-               ofs++;
-       }
-       pushchar(hash, 0);
+    pushchar(hash, p[ofs]);
+    pushchar(hash, '\n');
+    ofs++;
+  }
+  pushchar(hash, 0);
 }
 
-
 // Hash a file that consists of preprocessor output, but remove any line number
 // information from the hash.
 int
-unify_hash(struct hash *hash, const char *fname, bool debug)
+unify_hash(struct hash* hash, const char* fname, bool debug)
 {
-       char *data;
-       size_t size;
-       if (!read_file(fname, 0, &data, &size)) {
-               stats_update(STATS_PREPROCESSOR);
-               return -1;
-       }
-       print_unified = debug;
-       unify(hash, (unsigned char *)data, size);
-       free(data);
-       return 0;
+  char* data;
+  size_t size;
+  if (!read_file(fname, 0, &data, &size)) {
+    stats_update(STATS_PREPROCESSOR);
+    return -1;
+  }
+  print_unified = debug;
+  unify(hash, (unsigned char*)data, size);
+  free(data);
+  return 0;
 }
index eb6e6c4b79cbf6cdf439726e76900b547d958ad5..3629f693b355004bd740ea15ff286ee45f3e8067 100644 (file)
@@ -20,4 +20,4 @@
 
 #include "hash.hpp"
 
-int unify_hash(struct hash *hash, const char *fname, bool print);
+int unify_hash(struct hash* hash, const char* fname, bool print);
index ca0ec00b882e4f4b92fbc98770200b7d704a8bb6..26c7e499e74bfb305a44a92586da0f557dd228fe 100644 (file)
 #include "ccache.hpp"
 
 #ifdef HAVE_PWD_H
-#include <pwd.h>
+#  include <pwd.h>
 #endif
 #ifdef HAVE_SYSLOG_H
-#include <syslog.h>
+#  include <syslog.h>
 #endif
 #ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
+#  include <sys/time.h>
 #endif
 
 #ifdef __linux__
 #  ifdef HAVE_SYS_IOCTL_H
-#  include <sys/ioctl.h>
+#    include <sys/ioctl.h>
 #  endif
 #  ifdef HAVE_LINUX_FS_H
 #    include <linux/fs.h>
 #endif
 
 #ifdef _WIN32
-#include <windows.h>
-#include <sys/locking.h>
-#include <psapi.h>
-#include <tchar.h>
+#  include <psapi.h>
+#  include <sys/locking.h>
+#  include <tchar.h>
+#  include <windows.h>
 #endif
 
-extern const struct conf *conf;
+extern const struct confconf;
 
 // Destination for conf->log_file.
-static FILE *logfile;
+static FILElogfile;
 
 // Whether to use syslog() instead.
 static bool use_syslog;
 
 // Buffer used for logs in conf->debug mode.
-static char *debug_log_buffer;
+static chardebug_log_buffer;
 
 // Allocated debug_log_buffer size.
 static size_t debug_log_buffer_capacity;
@@ -78,96 +78,100 @@ static size_t debug_log_size;
 static bool
 init_log(void)
 {
-       if (debug_log_buffer || logfile || use_syslog) {
-               return true;
-       }
-       assert(conf);
-       if (conf->debug) {
-               debug_log_buffer_capacity = DEBUG_LOG_BUFFER_MARGIN;
-               debug_log_buffer = static_cast<char*>(x_malloc(debug_log_buffer_capacity));
-               debug_log_size = 0;
-       }
-       if (str_eq(conf->log_file, "")) {
-               return conf->debug;
-       }
+  if (debug_log_buffer || logfile || use_syslog) {
+    return true;
+  }
+  assert(conf);
+  if (conf->debug) {
+    debug_log_buffer_capacity = DEBUG_LOG_BUFFER_MARGIN;
+    debug_log_buffer = static_cast<char*>(x_malloc(debug_log_buffer_capacity));
+    debug_log_size = 0;
+  }
+  if (str_eq(conf->log_file, "")) {
+    return conf->debug;
+  }
 #ifdef HAVE_SYSLOG
-       if (str_eq(conf->log_file, "syslog")) {
-               use_syslog = true;
-               openlog("ccache", LOG_PID, LOG_USER);
-               return true;
-       }
+  if (str_eq(conf->log_file, "syslog")) {
+    use_syslog = true;
+    openlog("ccache", LOG_PID, LOG_USER);
+    return true;
+  }
 #endif
-       logfile = fopen(conf->log_file, "a");
-       if (logfile) {
+  logfile = fopen(conf->log_file, "a");
+  if (logfile) {
 #ifndef _WIN32
-               set_cloexec_flag(fileno(logfile));
+    set_cloexec_flag(fileno(logfile));
 #endif
-               return true;
-       } else {
-               return false;
-       }
+    return true;
+  } else {
+    return false;
+  }
 }
 
 static void
-append_to_debug_log(const char *s, size_t len)
+append_to_debug_log(const chars, size_t len)
 {
-       assert(debug_log_buffer);
-       if (debug_log_size + len + 1 > debug_log_buffer_capacity) {
-               debug_log_buffer_capacity += len + 1 + DEBUG_LOG_BUFFER_MARGIN;
-               debug_log_buffer = static_cast<char*>(
-                       x_realloc(debug_log_buffer, debug_log_buffer_capacity));
-       }
-       memcpy(debug_log_buffer + debug_log_size, s, len);
-       debug_log_size += len;
+  assert(debug_log_buffer);
+  if (debug_log_size + len + 1 > debug_log_buffer_capacity) {
+    debug_log_buffer_capacity += len + 1 + DEBUG_LOG_BUFFER_MARGIN;
+    debug_log_buffer = static_cast<char*>(
+      x_realloc(debug_log_buffer, debug_log_buffer_capacity));
+  }
+  memcpy(debug_log_buffer + debug_log_size, s, len);
+  debug_log_size += len;
 }
 
 static void
 log_prefix(bool log_updated_time)
 {
-       static char prefix[200];
+  static char prefix[200];
 #ifdef HAVE_GETTIMEOFDAY
-       if (log_updated_time) {
-               char timestamp[100];
-               struct tm tm;
-               struct timeval tv;
-               gettimeofday(&tv, NULL);
-#ifdef __MINGW64_VERSION_MAJOR
-               localtime_r((time_t *)&tv.tv_sec, &tm);
-#else
-               localtime_r(&tv.tv_sec, &tm);
-#endif
-               strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &tm);
-               snprintf(prefix, sizeof(prefix),
-                        "[%s.%06d %-5d] ", timestamp, (int)tv.tv_usec, (int)getpid());
-       }
+  if (log_updated_time) {
+    char timestamp[100];
+    struct tm tm;
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+#  ifdef __MINGW64_VERSION_MAJOR
+    localtime_r((time_t*)&tv.tv_sec, &tm);
+#  else
+    localtime_r(&tv.tv_sec, &tm);
+#  endif
+    strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &tm);
+    snprintf(prefix,
+             sizeof(prefix),
+             "[%s.%06d %-5d] ",
+             timestamp,
+             (int)tv.tv_usec,
+             (int)getpid());
+  }
 #else
-       snprintf(prefix, sizeof(prefix), "[%-5d] ", (int)getpid());
+  snprintf(prefix, sizeof(prefix), "[%-5d] ", (int)getpid());
 #endif
-       if (logfile) {
-               fputs(prefix, logfile);
-       }
+  if (logfile) {
+    fputs(prefix, logfile);
+  }
 #ifdef HAVE_SYSLOG
-       if (use_syslog) {
-               // prefix information will be added by syslog
-       }
+  if (use_syslog) {
+    // prefix information will be added by syslog
+  }
 #endif
-       if (debug_log_buffer) {
-               append_to_debug_log(prefix, strlen(prefix));
-       }
+  if (debug_log_buffer) {
+    append_to_debug_log(prefix, strlen(prefix));
+  }
 }
 
 static long
-path_max(const char *path)
+path_max(const charpath)
 {
 #ifdef PATH_MAX
-       (void)path;
-       return PATH_MAX;
+  (void)path;
+  return PATH_MAX;
 #elif defined(MAXPATHLEN)
-       (void)path;
-       return MAXPATHLEN;
+  (void)path;
+  return MAXPATHLEN;
 #elif defined(_PC_PATH_MAX)
-       long maxlen = pathconf(path, _PC_PATH_MAX);
-       return maxlen >= 4096 ? maxlen : 4096;
+  long maxlen = pathconf(path, _PC_PATH_MAX);
+  return maxlen >= 4096 ? maxlen : 4096;
 #endif
 }
 
@@ -177,185 +181,186 @@ static void warn_log_fail(void) ATTR_NORETURN;
 static void
 warn_log_fail(void)
 {
-       // Note: Can't call fatal() since that would lead to recursion.
-       fprintf(stderr, "ccache: error: Failed to write to %s: %s\n",
-               conf->log_file, strerror(errno));
-       x_exit(EXIT_FAILURE);
+  // Note: Can't call fatal() since that would lead to recursion.
+  fprintf(stderr,
+          "ccache: error: Failed to write to %s: %s\n",
+          conf->log_file,
+          strerror(errno));
+  x_exit(EXIT_FAILURE);
 }
 
 static void
-vlog(const char *format, va_list ap, bool log_updated_time)
-{
-       if (!init_log()) {
-               return;
-       }
-
-       va_list aq;
-       va_copy(aq, ap);
-       log_prefix(log_updated_time);
-       if (logfile) {
-               int rc1 = vfprintf(logfile, format, ap);
-               int rc2 = fprintf(logfile, "\n");
-               if (rc1 < 0 || rc2 < 0) {
-                       warn_log_fail();
-               }
-       }
+vlog(const charformat, va_list ap, bool log_updated_time)
+{
+  if (!init_log()) {
+    return;
+  }
+
+  va_list aq;
+  va_copy(aq, ap);
+  log_prefix(log_updated_time);
+  if (logfile) {
+    int rc1 = vfprintf(logfile, format, ap);
+    int rc2 = fprintf(logfile, "\n");
+    if (rc1 < 0 || rc2 < 0) {
+      warn_log_fail();
+    }
+  }
 #ifdef HAVE_SYSLOG
-       if (use_syslog) {
-               vsyslog(LOG_DEBUG, format, ap);
-       }
+  if (use_syslog) {
+    vsyslog(LOG_DEBUG, format, ap);
+  }
 #endif
-       if (debug_log_buffer) {
-               char buf[8192];
-               int len = vsnprintf(buf, sizeof(buf), format, aq);
-               if (len >= 0) {
-                       append_to_debug_log(buf, MIN((size_t)len, sizeof(buf) - 1));
-                       append_to_debug_log("\n", 1);
-               }
-       }
-       va_end(aq);
+  if (debug_log_buffer) {
+    char buf[8192];
+    int len = vsnprintf(buf, sizeof(buf), format, aq);
+    if (len >= 0) {
+      append_to_debug_log(buf, MIN((size_t)len, sizeof(buf) - 1));
+      append_to_debug_log("\n", 1);
+    }
+  }
+  va_end(aq);
 }
 
 // Write a message to the log file (adding a newline) and flush.
 void
-cc_log(const char *format, ...)
+cc_log(const charformat, ...)
 {
-       va_list ap;
-       va_start(ap, format);
-       vlog(format, ap, true);
-       va_end(ap);
-       if (logfile) {
-               fflush(logfile);
-       }
+  va_list ap;
+  va_start(ap, format);
+  vlog(format, ap, true);
+  va_end(ap);
+  if (logfile) {
+    fflush(logfile);
+  }
 }
 
 // Write a message to the log file (adding a newline) without flushing and with
 // a reused timestamp.
 void
-cc_bulklog(const char *format, ...)
+cc_bulklog(const charformat, ...)
 {
-       va_list ap;
-       va_start(ap, format);
-       vlog(format, ap, false);
-       va_end(ap);
+  va_list ap;
+  va_start(ap, format);
+  vlog(format, ap, false);
+  va_end(ap);
 }
 
 // Log an executed command to the CCACHE_LOGFILE location.
 void
-cc_log_argv(const char *prefix, char **argv)
-{
-       if (!init_log()) {
-               return;
-       }
-
-       log_prefix(true);
-       if (logfile) {
-               fputs(prefix, logfile);
-               print_command(logfile, argv);
-               int rc = fflush(logfile);
-               if (rc) {
-                       warn_log_fail();
-               }
-       }
+cc_log_argv(const char* prefix, char** argv)
+{
+  if (!init_log()) {
+    return;
+  }
+
+  log_prefix(true);
+  if (logfile) {
+    fputs(prefix, logfile);
+    print_command(logfile, argv);
+    int rc = fflush(logfile);
+    if (rc) {
+      warn_log_fail();
+    }
+  }
 #ifdef HAVE_SYSLOG
-       if (use_syslog) {
-               char *s = format_command(argv);
-               syslog(LOG_DEBUG, "%s", s);
-               free(s);
-       }
+  if (use_syslog) {
+    char* s = format_command(argv);
+    syslog(LOG_DEBUG, "%s", s);
+    free(s);
+  }
 #endif
-       if (debug_log_buffer) {
-               append_to_debug_log(prefix, strlen(prefix));
-               char *s = format_command(argv);
-               append_to_debug_log(s, strlen(s));
-               free(s);
-       }
+  if (debug_log_buffer) {
+    append_to_debug_log(prefix, strlen(prefix));
+    char* s = format_command(argv);
+    append_to_debug_log(s, strlen(s));
+    free(s);
+  }
 }
 
 // Copy the current log memory buffer to an output file.
 void
-cc_dump_debug_log_buffer(const char *path)
+cc_dump_debug_log_buffer(const charpath)
 {
-       FILE *file = fopen(path, "w");
-       if (file) {
-               (void) fwrite(debug_log_buffer, 1, debug_log_size, file);
-               fclose(file);
-       } else {
-               cc_log("Failed to open %s: %s", path, strerror(errno));
-       }
+  FILE* file = fopen(path, "w");
+  if (file) {
+    (void)fwrite(debug_log_buffer, 1, debug_log_size, file);
+    fclose(file);
+  } else {
+    cc_log("Failed to open %s: %s", path, strerror(errno));
+  }
 }
 
 // Something went badly wrong!
 void
-fatal(const char *format, ...)
+fatal(const charformat, ...)
 {
-       va_list ap;
-       va_start(ap, format);
-       char msg[8192];
-       vsnprintf(msg, sizeof(msg), format, ap);
-       va_end(ap);
+  va_list ap;
+  va_start(ap, format);
+  char msg[8192];
+  vsnprintf(msg, sizeof(msg), format, ap);
+  va_end(ap);
 
-       cc_log("FATAL: %s", msg);
-       fprintf(stderr, "ccache: error: %s\n", msg);
+  cc_log("FATAL: %s", msg);
+  fprintf(stderr, "ccache: error: %s\n", msg);
 
-       x_exit(1);
+  x_exit(1);
 }
 
 // Transform a name to a full path into the cache directory, creating needed
 // sublevels if needed. Caller frees.
-char *
-get_path_in_cache(const char *name, const char *suffix)
+char*
+get_path_in_cache(const char* name, const char* suffix)
 {
-       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;
-       }
+  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;
+  }
 
-       char *result =
-               format("%s/%s%s", path, name + conf->cache_dir_levels, suffix);
-       free(path);
-       return result;
+  char* result = format("%s/%s%s", path, name + conf->cache_dir_levels, suffix);
+  free(path);
+  return result;
 }
 
 // Copy all data from fd_in to fd_out.
 bool
 copy_fd(int fd_in, int fd_out)
 {
-       int n;
-       char buf[READ_BUFFER_SIZE];
-       while ((n = read(fd_in, buf, sizeof(buf))) > 0) {
-               ssize_t written = 0;
-               do {
-                       ssize_t count = write(fd_out, buf + written, n - written);
-                       if (count == -1) {
-                               if (errno != EAGAIN && errno != EINTR) {
-                                       return false;
-                               }
-                       } else {
-                               written += count;
-                       }
-               } while (written < n);
-       }
-
-       return true;
+  int n;
+  char buf[READ_BUFFER_SIZE];
+  while ((n = read(fd_in, buf, sizeof(buf))) > 0) {
+    ssize_t written = 0;
+    do {
+      ssize_t count = write(fd_out, buf + written, n - written);
+      if (count == -1) {
+        if (errno != EAGAIN && errno != EINTR) {
+          return false;
+        }
+      } else {
+        written += count;
+      }
+    } while (written < n);
+  }
+
+  return true;
 }
 
 #ifndef HAVE_MKSTEMP
 // Cheap and nasty mkstemp replacement.
 int
-mkstemp(char *name_template)
+mkstemp(charname_template)
 {
-#ifdef __GNUC__
-       #pragma GCC diagnostic push
-       #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
-       mktemp(name_template);
-#ifdef __GNUC__
-       #pragma GCC diagnostic pop
-#endif
-       return open(name_template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
+#  ifdef __GNUC__
+#    pragma GCC diagnostic push
+#    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#  endif
+  mktemp(name_template);
+#  ifdef __GNUC__
+#    pragma GCC diagnostic pop
+#  endif
+  return open(name_template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
 }
 #endif
 
@@ -363,1121 +368,1127 @@ mkstemp(char *name_template)
 static mode_t
 get_umask(void)
 {
-       static bool mask_retrieved = false;
-       static mode_t mask;
-       if (!mask_retrieved) {
-               mask = umask(0);
-               umask(mask);
-               mask_retrieved = true;
-       }
-       return mask;
+  static bool mask_retrieved = false;
+  static mode_t mask;
+  if (!mask_retrieved) {
+    mask = umask(0);
+    umask(mask);
+    mask_retrieved = true;
+  }
+  return mask;
 }
 #endif
 
 // Clone a file from src to dest. If via_tmp_file is true, the file is cloned
 // to a temporary file and then renamed to dest.
 bool
-clone_file(const char *src, const char *dest, bool via_tmp_file)
+clone_file(const char* src, const char* dest, bool via_tmp_file)
 {
-       bool result;
+  bool result;
 
 #ifdef FILE_CLONING_SUPPORTED
 
-#if defined(__linux__)
-       int src_fd = open(src, O_RDONLY);
-       if (src_fd == -1) {
-               return false;
-       }
-
-       int dest_fd;
-       char *tmp_file = NULL;
-       if (via_tmp_file) {
-               tmp_file = x_strdup(dest);
-               dest_fd = create_tmp_fd(&tmp_file);
-       } else {
-               dest_fd = open(dest, O_WRONLY | O_CREAT | O_BINARY, 0666);
-               if (dest_fd == -1) {
-                       close(dest_fd);
-                       close(src_fd);
-                       return false;
-               }
-       }
-
-       int saved_errno = 0;
-       if (ioctl(dest_fd, FICLONE, src_fd) == 0) {
-               result = true;
-       } else {
-               result = false;
-               saved_errno = errno;
-       }
-
-       close(dest_fd);
-       close(src_fd);
-
-       if (via_tmp_file) {
-               x_try_unlink(dest);
-               if (x_rename(tmp_file, dest) != 0) {
-                       result = false;
-               }
-               free(tmp_file);
-       }
-
-       errno = saved_errno;
-#elif defined(__APPLE__)
-       (void)via_tmp_file;
-       result = clonefile(src, dest, CLONE_NOOWNERCOPY) == 0;
-#endif
+#  if defined(__linux__)
+  int src_fd = open(src, O_RDONLY);
+  if (src_fd == -1) {
+    return false;
+  }
+
+  int dest_fd;
+  char* tmp_file = NULL;
+  if (via_tmp_file) {
+    tmp_file = x_strdup(dest);
+    dest_fd = create_tmp_fd(&tmp_file);
+  } else {
+    dest_fd = open(dest, O_WRONLY | O_CREAT | O_BINARY, 0666);
+    if (dest_fd == -1) {
+      close(dest_fd);
+      close(src_fd);
+      return false;
+    }
+  }
+
+  int saved_errno = 0;
+  if (ioctl(dest_fd, FICLONE, src_fd) == 0) {
+    result = true;
+  } else {
+    result = false;
+    saved_errno = errno;
+  }
+
+  close(dest_fd);
+  close(src_fd);
+
+  if (via_tmp_file) {
+    x_try_unlink(dest);
+    if (x_rename(tmp_file, dest) != 0) {
+      result = false;
+    }
+    free(tmp_file);
+  }
+
+  errno = saved_errno;
+#  elif defined(__APPLE__)
+  (void)via_tmp_file;
+  result = clonefile(src, dest, CLONE_NOOWNERCOPY) == 0;
+#  endif
 
 #else // FILE_CLONING_SUPPORTED
 
-       (void)src;
-       (void)dest;
-       (void)via_tmp_file;
-       errno = EOPNOTSUPP;
-       result = false;
+  (void)src;
+  (void)dest;
+  (void)via_tmp_file;
+  errno = EOPNOTSUPP;
+  result = false;
 
 #endif // FILE_CLONING_SUPPORTED
 
-       return result;
+  return result;
 }
 
 // Copy a file from src to dest. If via_tmp_file is true, the file is copied to
 // a temporary file and then renamed to dest.
 bool
-copy_file(const char *src, const char *dest, bool via_tmp_file)
-{
-       bool result = false;
-
-       int src_fd = open(src, O_RDONLY);
-       if (src_fd == -1) {
-               return false;
-       }
-
-       int dest_fd;
-       char *tmp_file = NULL;
-       if (via_tmp_file) {
-               tmp_file = x_strdup(dest);
-               dest_fd = create_tmp_fd(&tmp_file);
-       } else {
-               dest_fd = open(dest, O_WRONLY | O_CREAT | O_BINARY, 0666);
-               if (dest_fd == -1) {
-                       close(dest_fd);
-                       close(src_fd);
-                       return false;
-               }
-       }
-
-       if (copy_fd(src_fd, dest_fd)) {
-               result = true;
-       }
-
-       close(dest_fd);
-       close(src_fd);
-
-       if (via_tmp_file) {
-               x_try_unlink(dest);
-               if (x_rename(tmp_file, dest) != 0) {
-                       result = false;
-               }
-               free(tmp_file);
-       }
-
-       return result;
+copy_file(const char* src, const char* dest, bool via_tmp_file)
+{
+  bool result = false;
+
+  int src_fd = open(src, O_RDONLY);
+  if (src_fd == -1) {
+    return false;
+  }
+
+  int dest_fd;
+  char* tmp_file = NULL;
+  if (via_tmp_file) {
+    tmp_file = x_strdup(dest);
+    dest_fd = create_tmp_fd(&tmp_file);
+  } else {
+    dest_fd = open(dest, O_WRONLY | O_CREAT | O_BINARY, 0666);
+    if (dest_fd == -1) {
+      close(dest_fd);
+      close(src_fd);
+      return false;
+    }
+  }
+
+  if (copy_fd(src_fd, dest_fd)) {
+    result = true;
+  }
+
+  close(dest_fd);
+  close(src_fd);
+
+  if (via_tmp_file) {
+    x_try_unlink(dest);
+    if (x_rename(tmp_file, dest) != 0) {
+      result = false;
+    }
+    free(tmp_file);
+  }
+
+  return result;
 }
 
 // Run copy_file() and, if successful, delete the source file.
 bool
-move_file(const char *src, const char *dest)
+move_file(const char* src, const char* dest)
 {
-       bool ok = copy_file(src, dest, false);
-       if (ok) {
-               x_unlink(src);
-       }
-       return ok;
+  bool ok = copy_file(src, dest, false);
+  if (ok) {
+    x_unlink(src);
+  }
+  return ok;
 }
 
 // Make sure a directory exists.
 int
-create_dir(const char *dir)
-{
-       struct stat st;
-       if (stat(dir, &st) == 0) {
-               if (S_ISDIR(st.st_mode)) {
-                       return 0;
-               }
-               errno = ENOTDIR;
-               return 1;
-       }
-       if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
-               return 1;
-       }
-       return 0;
+create_dir(const chardir)
+{
+  struct stat st;
+  if (stat(dir, &st) == 0) {
+    if (S_ISDIR(st.st_mode)) {
+      return 0;
+    }
+    errno = ENOTDIR;
+    return 1;
+  }
+  if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
+    return 1;
+  }
+  return 0;
 }
 
 // Create directories leading to path. Returns 0 on success, otherwise -1.
 int
-create_parent_dirs(const char *path)
-{
-       int res;
-       char *parent = x_dirname(path);
-       struct stat st;
-       if (stat(parent, &st) == 0) {
-               if (S_ISDIR(st.st_mode)) {
-                       res = 0;
-               } else {
-                       res = -1;
-                       errno = ENOTDIR;
-               }
-       } else {
-               res = create_parent_dirs(parent);
-               if (res == 0) {
-                       res = mkdir(parent, 0777);
-                       // Have to handle the condition of the directory already existing because
-                       // the file system could have changed in between calling stat and
-                       // actually creating the directory. This can happen when there are
-                       // multiple instances of ccache running and trying to create the same
-                       // directory chain, which usually is the case when the cache root does
-                       // not initially exist. As long as one of the processes creates the
-                       // directories then our condition is satisfied and we avoid a race
-                       // condition.
-                       if (res != 0 && errno == EEXIST) {
-                               res = 0;
-                       }
-               } else {
-                       res = -1;
-               }
-       }
-       free(parent);
-       return res;
+create_parent_dirs(const charpath)
+{
+  int res;
+  char* parent = x_dirname(path);
+  struct stat st;
+  if (stat(parent, &st) == 0) {
+    if (S_ISDIR(st.st_mode)) {
+      res = 0;
+    } else {
+      res = -1;
+      errno = ENOTDIR;
+    }
+  } else {
+    res = create_parent_dirs(parent);
+    if (res == 0) {
+      res = mkdir(parent, 0777);
+      // Have to handle the condition of the directory already existing because
+      // the file system could have changed in between calling stat and
+      // actually creating the directory. This can happen when there are
+      // multiple instances of ccache running and trying to create the same
+      // directory chain, which usually is the case when the cache root does
+      // not initially exist. As long as one of the processes creates the
+      // directories then our condition is satisfied and we avoid a race
+      // condition.
+      if (res != 0 && errno == EEXIST) {
+        res = 0;
+      }
+    } else {
+      res = -1;
+    }
+  }
+  free(parent);
+  return res;
 }
 
 // Return a static string with the current hostname.
-const char *
+const char*
 get_hostname(void)
 {
-       static char hostname[260] = "";
+  static char hostname[260] = "";
 
-       if (hostname[0]) {
-               return hostname;
-       }
+  if (hostname[0]) {
+    return hostname;
+  }
 
-       strcpy(hostname, "unknown");
+  strcpy(hostname, "unknown");
 #if HAVE_GETHOSTNAME
-       gethostname(hostname, sizeof(hostname) - 1);
+  gethostname(hostname, sizeof(hostname) - 1);
 #elif defined(_WIN32)
-       const char *computer_name = getenv("COMPUTERNAME");
-       if (computer_name) {
-               snprintf(hostname, sizeof(hostname), "%s", computer_name);
-               return hostname;
-       }
-
-       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(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();
-               return hostname;
-       }
-
-       int result = gethostname(hostname, sizeof(hostname) - 1);
-       if (result != 0) {
-               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) &lp_msg_buf, 0, NULL);
-
-               LPVOID lp_display_buf = (LPVOID) LocalAlloc(
-                       LMEM_ZEROINIT,
-                       (lstrlen((LPCTSTR) lp_msg_buf) + lstrlen((LPCTSTR) __FILE__) + 200)
-                       * sizeof(TCHAR));
-               _snprintf((LPTSTR) lp_display_buf,
-                         LocalSize(lp_display_buf) / sizeof(TCHAR),
-                         TEXT("%s failed with error %lu: %s"), __FILE__, dw,
-                         (const char *)lp_msg_buf);
-
-               cc_log("can't get hostname OS returned error: %s", (char *)lp_display_buf);
-
-               LocalFree(lp_msg_buf);
-               LocalFree(lp_display_buf);
-       }
-       WSACleanup();
+  const char* computer_name = getenv("COMPUTERNAME");
+  if (computer_name) {
+    snprintf(hostname, sizeof(hostname), "%s", computer_name);
+    return hostname;
+  }
+
+  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(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();
+    return hostname;
+  }
+
+  int result = gethostname(hostname, sizeof(hostname) - 1);
+  if (result != 0) {
+    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)&lp_msg_buf,
+                  0,
+                  NULL);
+
+    LPVOID lp_display_buf = (LPVOID)LocalAlloc(
+      LMEM_ZEROINIT,
+      (lstrlen((LPCTSTR)lp_msg_buf) + lstrlen((LPCTSTR)__FILE__) + 200)
+        * sizeof(TCHAR));
+    _snprintf((LPTSTR)lp_display_buf,
+              LocalSize(lp_display_buf) / sizeof(TCHAR),
+              TEXT("%s failed with error %lu: %s"),
+              __FILE__,
+              dw,
+              (const char*)lp_msg_buf);
+
+    cc_log("can't get hostname OS returned error: %s", (char*)lp_display_buf);
+
+    LocalFree(lp_msg_buf);
+    LocalFree(lp_display_buf);
+  }
+  WSACleanup();
 #endif
 
-       hostname[sizeof(hostname) - 1] = 0;
-       return hostname;
+  hostname[sizeof(hostname) - 1] = 0;
+  return hostname;
 }
 
 // Return a string to be passed to mkstemp to create a temporary file. Also
 // tries to cope with NFS by adding the local hostname.
-const char *
+const char*
 tmp_string(void)
 {
-       static char *ret;
-       if (!ret) {
-               ret = format("%s.%u.XXXXXX", get_hostname(), (unsigned)getpid());
-       }
-       return ret;
+  static char* ret;
+  if (!ret) {
+    ret = format("%s.%u.XXXXXX", get_hostname(), (unsigned)getpid());
+  }
+  return ret;
 }
 
 static char const CACHEDIR_TAG[] =
-       "Signature: 8a477f597d28d172789f06886806bc55\n"
-       "# This file is a cache directory tag created by ccache.\n"
-       "# For information about cache directory tags, see:\n"
-       "#\thttp://www.brynosaurus.com/cachedir/\n";
+  "Signature: 8a477f597d28d172789f06886806bc55\n"
+  "# This file is a cache directory tag created by ccache.\n"
+  "# For information about cache directory tags, see:\n"
+  "#\thttp://www.brynosaurus.com/cachedir/\n";
 
 int
-create_cachedirtag(const char *dir)
-{
-       char *filename = format("%s/CACHEDIR.TAG", dir);
-       FILE* f;
-       struct stat st;
-
-       if (stat(filename, &st) == 0) {
-               if (S_ISREG(st.st_mode)) {
-                       goto success;
-               }
-               errno = EEXIST;
-               goto error;
-       }
-
-       f = fopen(filename, "w");
-       if (!f) {
-               goto error;
-       }
-       if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG)-1, 1, f) != 1) {
-               fclose(f);
-               goto error;
-       }
-       if (fclose(f)) {
-               goto error;
-       }
+create_cachedirtag(const chardir)
+{
+  char* filename = format("%s/CACHEDIR.TAG", dir);
+  FILE* f;
+  struct stat st;
+
+  if (stat(filename, &st) == 0) {
+    if (S_ISREG(st.st_mode)) {
+      goto success;
+    }
+    errno = EEXIST;
+    goto error;
+  }
+
+  f = fopen(filename, "w");
+  if (!f) {
+    goto error;
+  }
+  if (fwrite(CACHEDIR_TAG, sizeof(CACHEDIR_TAG) - 1, 1, f) != 1) {
+    fclose(f);
+    goto error;
+  }
+  if (fclose(f)) {
+    goto error;
+  }
 success:
-       free(filename);
-       return 0;
+  free(filename);
+  return 0;
 error:
-       free(filename);
-       return 1;
+  free(filename);
+  return 1;
 }
 
 // Construct a string according to a format. Caller frees.
-char *
-format(const char *format, ...)
+char*
+format(const charformat, ...)
 {
-       va_list ap;
-       va_start(ap, format);
+  va_list ap;
+  va_start(ap, format);
 
-       char *ptr = NULL;
-       if (vasprintf(&ptr, format, ap) == -1) {
-               fatal("Out of memory in format");
-       }
-       va_end(ap);
+  char* ptr = NULL;
+  if (vasprintf(&ptr, format, ap) == -1) {
+    fatal("Out of memory in format");
+  }
+  va_end(ap);
 
-       if (!*ptr) {
-               fatal("Internal error in format");
-       }
-       return ptr;
+  if (!*ptr) {
+    fatal("Internal error in format");
+  }
+  return ptr;
 }
 
 // Construct a hexadecimal string representing binary data. The buffer must
 // hold at least 2 * size + 1 bytes.
 void
-format_hex(const uint8_t *data, size_t size, char *buffer)
+format_hex(const uint8_t* data, size_t size, char* buffer)
 {
-       for (size_t i = 0; i < size; i++) {
-               sprintf(&buffer[i*2], "%02x", (unsigned)data[i]);
-       }
-       buffer[2 * size] = '\0';
+  for (size_t i = 0; i < size; i++) {
+    sprintf(&buffer[i * 2], "%02x", (unsigned)data[i]);
+  }
+  buffer[2 * size] = '\0';
 }
 
 // This is like strdup() but dies if the malloc fails.
-char *
-x_strdup(const char *s)
+char*
+x_strdup(const chars)
 {
-       char *ret = strdup(s);
-       if (!ret) {
-               fatal("Out of memory in x_strdup");
-       }
-       return ret;
+  char* ret = strdup(s);
+  if (!ret) {
+    fatal("Out of memory in x_strdup");
+  }
+  return ret;
 }
 
 // This is like strndup() but dies if the malloc fails.
-char *
-x_strndup(const char *s, size_t n)
+char*
+x_strndup(const chars, size_t n)
 {
 #ifndef HAVE_STRNDUP
-       if (!s) {
-               return NULL;
-       }
-       size_t m = 0;
-       while (m < n && s[m]) {
-               m++;
-       }
-       char *ret = static_cast<char*>(malloc(m + 1));
-       if (ret) {
-               memcpy(ret, s, m);
-               ret[m] = '\0';
-       }
+  if (!s) {
+    return NULL;
+  }
+  size_t m = 0;
+  while (m < n && s[m]) {
+    m++;
+  }
+  char* ret = static_cast<char*>(malloc(m + 1));
+  if (ret) {
+    memcpy(ret, s, m);
+    ret[m] = '\0';
+  }
 #else
-       char *ret = strndup(s, n);
+  char* ret = strndup(s, n);
 #endif
-       if (!ret) {
-               fatal("x_strndup: Could not allocate %lu bytes", (unsigned long)n);
-       }
-       return ret;
+  if (!ret) {
+    fatal("x_strndup: Could not allocate %lu bytes", (unsigned long)n);
+  }
+  return ret;
 }
 
 // This is like malloc() but dies if the malloc fails.
-void *
+void*
 x_malloc(size_t size)
 {
-       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;
-       }
-       void *ret = malloc(size);
-       if (!ret) {
-               fatal("x_malloc: Could not allocate %lu bytes", (unsigned long)size);
-       }
-       return 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;
+  }
+  void* ret = malloc(size);
+  if (!ret) {
+    fatal("x_malloc: Could not allocate %lu bytes", (unsigned long)size);
+  }
+  return ret;
 }
 
 // This is like calloc() but dies if the allocation fails.
-void *
+void*
 x_calloc(size_t nmemb, size_t size)
 {
-       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;
-       }
-       void *ret = calloc(nmemb, size);
-       if (!ret) {
-               fatal("x_calloc: Could not allocate %lu bytes", (unsigned long)size);
-       }
-       return 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;
+  }
+  void* ret = calloc(nmemb, size);
+  if (!ret) {
+    fatal("x_calloc: Could not allocate %lu bytes", (unsigned long)size);
+  }
+  return ret;
 }
 
 // This is like realloc() but dies if the malloc fails.
-void *
-x_realloc(void *ptr, size_t size)
+void*
+x_realloc(voidptr, size_t size)
 {
-       if (!ptr) {
-               return x_malloc(size);
-       }
-       void *p2 = realloc(ptr, size);
-       if (!p2) {
-               fatal("x_realloc: Could not allocate %lu bytes", (unsigned long)size);
-       }
-       return p2;
+  if (!ptr) {
+    return x_malloc(size);
+  }
+  void* p2 = realloc(ptr, size);
+  if (!p2) {
+    fatal("x_realloc: Could not allocate %lu bytes", (unsigned long)size);
+  }
+  return p2;
 }
 
 // This is like setenv.
-void x_setenv(const char *name, const char *value)
+void
+x_setenv(const char* name, const char* value)
 {
 #ifdef HAVE_SETENV
-       setenv(name, value, true);
+  setenv(name, value, true);
 #else
-       putenv(format("%s=%s", name, value)); // Leak to environment.
+  putenv(format("%s=%s", name, value)); // Leak to environment.
 #endif
 }
 
 // This is like unsetenv.
-void x_unsetenv(const char *name)
+void
+x_unsetenv(const char* name)
 {
 #ifdef HAVE_UNSETENV
-       unsetenv(name);
+  unsetenv(name);
 #else
-       putenv(x_strdup(name)); // Leak to environment.
+  putenv(x_strdup(name));               // Leak to environment.
 #endif
 }
 
 // Like fstat() but also call cc_log on failure.
 int
-x_fstat(int fd, struct stat *buf)
+x_fstat(int fd, struct statbuf)
 {
-       int result = fstat(fd, buf);
-       if (result != 0) {
-               cc_log("Failed to fstat fd %d: %s", fd, strerror(errno));
-       }
-       return result;
+  int result = fstat(fd, buf);
+  if (result != 0) {
+    cc_log("Failed to fstat fd %d: %s", fd, strerror(errno));
+  }
+  return result;
 }
 
 // Like lstat() but also call cc_log on failure.
 int
-x_lstat(const char *pathname, struct stat *buf)
+x_lstat(const char* pathname, struct stat* buf)
 {
-       int result = lstat(pathname, buf);
-       if (result != 0) {
-               cc_log("Failed to lstat %s: %s", pathname, strerror(errno));
-       }
-       return result;
+  int result = lstat(pathname, buf);
+  if (result != 0) {
+    cc_log("Failed to lstat %s: %s", pathname, strerror(errno));
+  }
+  return result;
 }
 
 // Like stat() but also call cc_log on failure.
 int
-x_stat(const char *pathname, struct stat *buf)
+x_stat(const char* pathname, struct stat* buf)
 {
-       int result = stat(pathname, buf);
-       if (result != 0) {
-               cc_log("Failed to stat %s: %s", pathname, strerror(errno));
-       }
-       return result;
+  int result = stat(pathname, buf);
+  if (result != 0) {
+    cc_log("Failed to stat %s: %s", pathname, strerror(errno));
+  }
+  return result;
 }
 
 // Construct a string according to the format and store it in *ptr. The
 // original *ptr is then freed.
 void
-reformat(char **ptr, const char *format, ...)
+reformat(char** ptr, const char* format, ...)
 {
-       char *saved = *ptr;
-       *ptr = NULL;
+  char* saved = *ptr;
+  *ptr = NULL;
 
-       va_list ap;
-       va_start(ap, format);
-       if (vasprintf(ptr, format, ap) == -1) {
-               fatal("Out of memory in reformat");
-       }
-       va_end(ap);
+  va_list ap;
+  va_start(ap, format);
+  if (vasprintf(ptr, format, ap) == -1) {
+    fatal("Out of memory in reformat");
+  }
+  va_end(ap);
 
-       if (saved) {
-               free(saved);
-       }
+  if (saved) {
+    free(saved);
+  }
 }
 
 // Recursive directory traversal. fn() is called on all entries in the tree.
 void
-traverse(const char *dir, void (*fn)(const char *, struct stat *))
-{
-       DIR *d = opendir(dir);
-       if (!d) {
-               return;
-       }
-
-       struct dirent *de;
-       while ((de = readdir(d))) {
-               if (str_eq(de->d_name, ".")) {
-                       continue;
-               }
-               if (str_eq(de->d_name, "..")) {
-                       continue;
-               }
-
-               if (strlen(de->d_name) == 0) {
-                       continue;
-               }
-
-               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));
-                       }
-                       free(fname);
-                       continue;
-               }
-
-               if (S_ISDIR(st.st_mode)) {
-                       traverse(fname, fn);
-               }
-
-               fn(fname, &st);
-               free(fname);
-       }
-
-       closedir(d);
+traverse(const char* dir, void (*fn)(const char*, struct stat*))
+{
+  DIR* d = opendir(dir);
+  if (!d) {
+    return;
+  }
+
+  struct dirent* de;
+  while ((de = readdir(d))) {
+    if (str_eq(de->d_name, ".")) {
+      continue;
+    }
+    if (str_eq(de->d_name, "..")) {
+      continue;
+    }
+
+    if (strlen(de->d_name) == 0) {
+      continue;
+    }
+
+    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));
+      }
+      free(fname);
+      continue;
+    }
+
+    if (S_ISDIR(st.st_mode)) {
+      traverse(fname, fn);
+    }
+
+    fn(fname, &st);
+    free(fname);
+  }
+
+  closedir(d);
 }
 
-
 // Return the base name of a file - caller frees.
-char *
-x_basename(const char *path)
+char*
+x_basename(const charpath)
 {
-       const char *p = strrchr(path, '/');
-       if (p) {
-               path = p + 1;
-       }
+  const char* p = strrchr(path, '/');
+  if (p) {
+    path = p + 1;
+  }
 #ifdef _WIN32
-       p = strrchr(path, '\\');
-       if (p) {
-               path = p + 1;
-       }
+  p = strrchr(path, '\\');
+  if (p) {
+    path = p + 1;
+  }
 #endif
 
-       return x_strdup(path);
+  return x_strdup(path);
 }
 
 // Return the dir name of a file - caller frees.
-char *
-x_dirname(const char *path)
+char*
+x_dirname(const charpath)
 {
-       char *s = x_strdup(path);
-       char *p = strrchr(s, '/');
+  char* s = x_strdup(path);
+  char* p = strrchr(s, '/');
 #ifdef _WIN32
-       char *p2 = strrchr(s, '\\');
-       if (!p || (p2 && p < p2)) {
-               p = p2;
-       }
+  char* p2 = strrchr(s, '\\');
+  if (!p || (p2 && p < p2)) {
+    p = p2;
+  }
 #endif
-       if (!p) {
-               free(s);
-               s = x_strdup(".");
-       } else if (p == s) {
-               *(p + 1) = 0;
-       } else {
-               *p = 0;
-       }
-       return s;
+  if (!p) {
+    free(s);
+    s = x_strdup(".");
+  } else if (p == s) {
+    *(p + 1) = 0;
+  } else {
+    *p = 0;
+  }
+  return s;
 }
 
 // Return the file extension (including the dot) of a path as a pointer into
 // path. If path has no file extension, the empty string and the end of path is
 // returned.
-const char *
-get_extension(const char *path)
+const char*
+get_extension(const charpath)
 {
-       size_t len = strlen(path);
-       for (const char *p = &path[len - 1]; p >= path; --p) {
-               if (*p == '.') {
-                       return p;
-               }
-               if (*p == '/') {
-                       break;
-               }
-       }
-       return &path[len];
+  size_t len = strlen(path);
+  for (const char* p = &path[len - 1]; p >= path; --p) {
+    if (*p == '.') {
+      return p;
+    }
+    if (*p == '/') {
+      break;
+    }
+  }
+  return &path[len];
 }
 
 // Return a string containing the given path without the filename extension.
 // Caller frees.
-char *
-remove_extension(const char *path)
+char*
+remove_extension(const charpath)
 {
-       return x_strndup(path, strlen(path) - strlen(get_extension(path)));
+  return x_strndup(path, strlen(path) - strlen(get_extension(path)));
 }
 
 // Return size on disk of a file.
 size_t
-file_size(struct stat *st)
+file_size(struct statst)
 {
 #ifdef _WIN32
-       return (st->st_size + 1023) & ~1023;
+  return (st->st_size + 1023) & ~1023;
 #else
-       return st->st_blocks * 512;
+  return st->st_blocks * 512;
 #endif
 }
 
 // Format a size as a human-readable string. Caller frees.
-char *
+char*
 format_human_readable_size(uint64_t v)
 {
-       char *s;
-       if (v >= 1000*1000*1000) {
-               s = format("%.1f GB", v/((double)(1000*1000*1000)));
-       } else {
-               s = format("%.1f MB", v/((double)(1000*1000)));
-       }
-       return s;
+  char* s;
+  if (v >= 1000 * 1000 * 1000) {
+    s = format("%.1f GB", v / ((double)(1000 * 1000 * 1000)));
+  } else {
+    s = format("%.1f MB", v / ((double)(1000 * 1000)));
+  }
+  return s;
 }
 
 // Format a size as a parsable string. Caller frees.
-char *
+char*
 format_parsable_size_with_suffix(uint64_t size)
 {
-       char *s;
-       if (size >= 1000*1000*1000) {
-               s = format("%.1fG", size / ((double)(1000*1000*1000)));
-       } else if (size >= 1000*1000) {
-               s = format("%.1fM", size / ((double)(1000*1000)));
-       } else {
-               s = format("%u", (unsigned)size);
-       }
-       return s;
+  char* s;
+  if (size >= 1000 * 1000 * 1000) {
+    s = format("%.1fG", size / ((double)(1000 * 1000 * 1000)));
+  } else if (size >= 1000 * 1000) {
+    s = format("%.1fM", size / ((double)(1000 * 1000)));
+  } else {
+    s = format("%u", (unsigned)size);
+  }
+  return s;
 }
 
 // Parse a "size value", i.e. a string that can end in k, M, G, T (10-based
 // suffixes) or Ki, Mi, Gi, Ti (2-based suffixes). For backward compatibility,
 // K is also recognized as a synonym of k.
 bool
-parse_size_with_suffix(const char *str, uint64_t *size)
-{
-       errno = 0;
-
-       char *p;
-       double x = strtod(str, &p);
-       if (errno != 0 || x < 0 || p == str || *str == '\0') {
-               return false;
-       }
-
-       while (isspace(*p)) {
-               ++p;
-       }
-
-       if (*p != '\0') {
-               unsigned multiplier = *(p+1) == 'i' ? 1024 : 1000;
-               switch (*p) {
-               case 'T':
-                       x *= multiplier;
-               // Fallthrough.
-               case 'G':
-                       x *= multiplier;
-               // Fallthrough.
-               case 'M':
-                       x *= multiplier;
-               // Fallthrough.
-               case 'K':
-               case 'k':
-                       x *= multiplier;
-                       break;
-               default:
-                       return false;
-               }
-       } else {
-               // Default suffix: G.
-               x *= 1000 * 1000 * 1000;
-       }
-       *size = (uint64_t)x;
-       return true;
-}
-
-
-#if !defined(HAVE_REALPATH) && \
-  defined(_WIN32) && \
-  !defined(HAVE_GETFINALPATHNAMEBYHANDLEW)
-static BOOL GetFileNameFromHandle(HANDLE file_handle, TCHAR *filename,
-                                  WORD cch_filename)
-{
-       BOOL success = FALSE;
-
-       // Get the file size.
-       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.
-       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 *mem = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 1);
-       if (mem) {
-               if (GetMappedFileName(GetCurrentProcess(),
-                                     mem,
-                                     filename,
-                                     cch_filename)) {
-                       // Translate path with device name to drive letters.
-                       TCHAR temp[512];
-                       temp[0] = '\0';
-
-                       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.
-                                       *drive = *p;
-
-                                       // Look up each device name.
-                                       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"),
-                                                                          drive,
-                                                                          filename+name_len);
-                                                               strcpy(filename, temp_file);
-                                                       }
-                                               }
-                                       }
-
-                                       // Go to the next NULL character.
-                                       while (*p++) {
-                                               // Do nothing.
-                                       }
-                               } while (!found && *p); // End of string.
-                       }
-               }
-               success = TRUE;
-               UnmapViewOfFile(mem);
-       }
-
-       CloseHandle(file_map);
-       return success;
+parse_size_with_suffix(const char* str, uint64_t* size)
+{
+  errno = 0;
+
+  char* p;
+  double x = strtod(str, &p);
+  if (errno != 0 || x < 0 || p == str || *str == '\0') {
+    return false;
+  }
+
+  while (isspace(*p)) {
+    ++p;
+  }
+
+  if (*p != '\0') {
+    unsigned multiplier = *(p + 1) == 'i' ? 1024 : 1000;
+    switch (*p) {
+    case 'T':
+      x *= multiplier;
+    // Fallthrough.
+    case 'G':
+      x *= multiplier;
+    // Fallthrough.
+    case 'M':
+      x *= multiplier;
+    // Fallthrough.
+    case 'K':
+    case 'k':
+      x *= multiplier;
+      break;
+    default:
+      return false;
+    }
+  } else {
+    // Default suffix: G.
+    x *= 1000 * 1000 * 1000;
+  }
+  *size = (uint64_t)x;
+  return true;
+}
+
+#if !defined(HAVE_REALPATH) && defined(_WIN32)                                 \
+  && !defined(HAVE_GETFINALPATHNAMEBYHANDLEW)
+static BOOL
+GetFileNameFromHandle(HANDLE file_handle, TCHAR* filename, WORD cch_filename)
+{
+  BOOL success = FALSE;
+
+  // Get the file size.
+  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.
+  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* mem = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 1);
+  if (mem) {
+    if (GetMappedFileName(GetCurrentProcess(), mem, filename, cch_filename)) {
+      // Translate path with device name to drive letters.
+      TCHAR temp[512];
+      temp[0] = '\0';
+
+      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.
+          *drive = *p;
+
+          // Look up each device name.
+          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"),
+                           drive,
+                           filename + name_len);
+                strcpy(filename, temp_file);
+              }
+            }
+          }
+
+          // Go to the next NULL character.
+          while (*p++) {
+            // Do nothing.
+          }
+        } while (!found && *p); // End of string.
+      }
+    }
+    success = TRUE;
+    UnmapViewOfFile(mem);
+  }
+
+  CloseHandle(file_map);
+  return success;
 }
 #endif
 
 // A sane realpath() function, trying to cope with stupid path limits and a
 // broken API. Caller frees.
-char *
-x_realpath(const char *path)
+char*
+x_realpath(const charpath)
 {
-       long maxlen = path_max(path);
-       char *ret = static_cast<char*>(x_malloc(maxlen));
-       char *p;
+  long maxlen = path_max(path);
+  char* ret = static_cast<char*>(x_malloc(maxlen));
+  char* p;
 
 #if HAVE_REALPATH
-       p = realpath(path, ret);
+  p = realpath(path, ret);
 #elif defined(_WIN32)
-       if (path[0] == '/') {
-               path++;  // Skip leading slash.
-       }
-       HANDLE path_handle = CreateFile(
-               path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
-               FILE_ATTRIBUTE_NORMAL, NULL);
-       if (INVALID_HANDLE_VALUE != path_handle) {
-#ifdef HAVE_GETFINALPATHNAMEBYHANDLEW
-               GetFinalPathNameByHandle(path_handle, ret, maxlen, FILE_NAME_NORMALIZED);
-#else
-               GetFileNameFromHandle(path_handle, ret, maxlen);
-#endif
-               CloseHandle(path_handle);
-               p = ret + 4; // Strip \\?\ from the file name.
-       } else {
-               snprintf(ret, maxlen, "%s", path);
-               p = ret;
-       }
+  if (path[0] == '/') {
+    path++; // Skip leading slash.
+  }
+  HANDLE path_handle = CreateFile(path,
+                                  GENERIC_READ,
+                                  FILE_SHARE_READ,
+                                  NULL,
+                                  OPEN_EXISTING,
+                                  FILE_ATTRIBUTE_NORMAL,
+                                  NULL);
+  if (INVALID_HANDLE_VALUE != path_handle) {
+#  ifdef HAVE_GETFINALPATHNAMEBYHANDLEW
+    GetFinalPathNameByHandle(path_handle, ret, maxlen, FILE_NAME_NORMALIZED);
+#  else
+    GetFileNameFromHandle(path_handle, ret, maxlen);
+#  endif
+    CloseHandle(path_handle);
+    p = ret + 4; // Strip \\?\ from the file name.
+  } else {
+    snprintf(ret, maxlen, "%s", path);
+    p = ret;
+  }
 #else
-       // Yes, there are such systems. This replacement relies on the fact that when
-       // we call x_realpath we only care about symlinks.
-       {
-               int len = readlink(path, ret, maxlen-1);
-               if (len == -1) {
-                       free(ret);
-                       return NULL;
-               }
-               ret[len] = 0;
-               p = ret;
-       }
+  // Yes, there are such systems. This replacement relies on the fact that when
+  // we call x_realpath we only care about symlinks.
+  {
+    int len = readlink(path, ret, maxlen - 1);
+    if (len == -1) {
+      free(ret);
+      return NULL;
+    }
+    ret[len] = 0;
+    p = ret;
+  }
 #endif
-       if (p) {
-               p = x_strdup(p);
-               free(ret);
-               return p;
-       }
-       free(ret);
-       return NULL;
+  if (p) {
+    p = x_strdup(p);
+    free(ret);
+    return p;
+  }
+  free(ret);
+  return NULL;
 }
 
 // A getcwd that will returns an allocated buffer.
-char *
+char*
 gnu_getcwd(void)
 {
-       unsigned size = 128;
+  unsigned size = 128;
 
-       while (true) {
-               char *buffer = (char *)x_malloc(size);
-               if (getcwd(buffer, size) == buffer) {
-                       return buffer;
-               }
-               free(buffer);
-               if (errno != ERANGE) {
-                       cc_log("getcwd error: %d (%s)", errno, strerror(errno));
-                       return NULL;
-               }
-               size *= 2;
-       }
+  while (true) {
+    char* buffer = (char*)x_malloc(size);
+    if (getcwd(buffer, size) == buffer) {
+      return buffer;
+    }
+    free(buffer);
+    if (errno != ERANGE) {
+      cc_log("getcwd error: %d (%s)", errno, strerror(errno));
+      return NULL;
+    }
+    size *= 2;
+  }
 }
 
 #if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R)
 // localtime_r replacement. (Mingw-w64 has an inline localtime_r which is not
 // detected by AC_CHECK_FUNCS.)
-struct tm *
-localtime_r(const time_t *timep, struct tm *result)
+struct tm*
+localtime_r(const time_t* timep, struct tm* result)
 {
-       struct tm *tm = localtime(timep);
-       *result = *tm;
-       return result;
+  struct tm* tm = localtime(timep);
+  *result = *tm;
+  return result;
 }
 #endif
 
 #ifndef HAVE_STRTOK_R
 // strtok_r replacement.
-char *
-strtok_r(char *str, const char *delim, char **saveptr)
-{
-       if (!str) {
-               str = *saveptr;
-       }
-       int len = strlen(str);
-       char *ret = strtok(str, delim);
-       if (ret) {
-               char *save = ret;
-               while (*save++) {
-                       // Do nothing.
-               }
-               if ((len + 1) == (intptr_t) (save - str)) {
-                       save--;
-               }
-               *saveptr = save;
-       }
-       return ret;
+char*
+strtok_r(char* str, const char* delim, char** saveptr)
+{
+  if (!str) {
+    str = *saveptr;
+  }
+  int len = strlen(str);
+  char* ret = strtok(str, delim);
+  if (ret) {
+    char* save = ret;
+    while (*save++) {
+      // Do nothing.
+    }
+    if ((len + 1) == (intptr_t)(save - str)) {
+      save--;
+    }
+    *saveptr = save;
+  }
+  return ret;
 }
 #endif
 
 // Create an empty temporary file. *fname will be reallocated and set to the
 // resulting filename. Returns an open file descriptor to the file.
 int
-create_tmp_fd(char **fname)
-{
-       char *tmpl = format("%s.%s", *fname, tmp_string());
-       int fd = mkstemp(tmpl);
-       if (fd == -1 && errno == ENOENT) {
-               if (create_parent_dirs(*fname) != 0) {
-                       fatal("Failed to create directory %s: %s",
-                             x_dirname(*fname), strerror(errno));
-               }
-               reformat(&tmpl, "%s.%s", *fname, tmp_string());
-               fd = mkstemp(tmpl);
-       }
-       if (fd == -1) {
-               fatal("Failed to create temporary file for %s: %s",
-                     *fname, strerror(errno));
-       }
-       set_cloexec_flag(fd);
+create_tmp_fd(char** fname)
+{
+  char* tmpl = format("%s.%s", *fname, tmp_string());
+  int fd = mkstemp(tmpl);
+  if (fd == -1 && errno == ENOENT) {
+    if (create_parent_dirs(*fname) != 0) {
+      fatal("Failed to create directory %s: %s",
+            x_dirname(*fname),
+            strerror(errno));
+    }
+    reformat(&tmpl, "%s.%s", *fname, tmp_string());
+    fd = mkstemp(tmpl);
+  }
+  if (fd == -1) {
+    fatal(
+      "Failed to create temporary file for %s: %s", *fname, strerror(errno));
+  }
+  set_cloexec_flag(fd);
 
 #ifndef _WIN32
-       fchmod(fd, 0666 & ~get_umask());
+  fchmod(fd, 0666 & ~get_umask());
 #endif
 
-       free(*fname);
-       *fname = tmpl;
-       return fd;
+  free(*fname);
+  *fname = tmpl;
+  return fd;
 }
 
 // Create an empty temporary file. *fname will be reallocated and set to the
 // resulting filename. Returns an open FILE*.
-FILE *
-create_tmp_file(char **fname, const char *mode)
+FILE*
+create_tmp_file(char** fname, const char* mode)
 {
-       FILE *file = fdopen(create_tmp_fd(fname), mode);
-       if (!file) {
-               fatal("Failed to create file %s: %s", *fname, strerror(errno));
-       }
-       return file;
+  FILE* file = fdopen(create_tmp_fd(fname), mode);
+  if (!file) {
+    fatal("Failed to create file %s: %s", *fname, strerror(errno));
+  }
+  return file;
 }
 
 // Return current user's home directory, or NULL if it can't be determined.
-const char *
+const char*
 get_home_directory(void)
 {
-       const char *p = getenv("HOME");
-       if (p) {
-               return p;
-       }
+  const char* p = getenv("HOME");
+  if (p) {
+    return p;
+  }
 #ifdef _WIN32
-       p = getenv("APPDATA");
-       if (p) {
-               return p;
-       }
+  p = getenv("APPDATA");
+  if (p) {
+    return p;
+  }
 #endif
 #ifdef HAVE_GETPWUID
-       {
-               struct passwd *pwd = getpwuid(getuid());
-               if (pwd) {
-                       return pwd->pw_dir;
-               }
-       }
+  {
+    struct passwd* pwd = getpwuid(getuid());
+    if (pwd) {
+      return pwd->pw_dir;
+    }
+  }
 #endif
-       return NULL;
+  return NULL;
 }
 
 // Get the current directory by reading $PWD. If $PWD isn't sane, gnu_getcwd()
 // is used. Caller frees.
-char *
+char*
 get_cwd(void)
 {
-       struct stat st_pwd;
-       struct stat st_cwd;
-
-       char *cwd = gnu_getcwd();
-       if (!cwd) {
-               return NULL;
-       }
-       char *pwd = getenv("PWD");
-       if (!pwd) {
-               return cwd;
-       }
-       if (stat(pwd, &st_pwd) != 0) {
-               return cwd;
-       }
-       if (stat(cwd, &st_cwd) != 0) {
-               return cwd;
-       }
-       if (st_pwd.st_dev == st_cwd.st_dev && st_pwd.st_ino == st_cwd.st_ino) {
-               free(cwd);
-               return x_strdup(pwd);
-       } else {
-               return cwd;
-       }
+  struct stat st_pwd;
+  struct stat st_cwd;
+
+  char* cwd = gnu_getcwd();
+  if (!cwd) {
+    return NULL;
+  }
+  char* pwd = getenv("PWD");
+  if (!pwd) {
+    return cwd;
+  }
+  if (stat(pwd, &st_pwd) != 0) {
+    return cwd;
+  }
+  if (stat(cwd, &st_cwd) != 0) {
+    return cwd;
+  }
+  if (st_pwd.st_dev == st_cwd.st_dev && st_pwd.st_ino == st_cwd.st_ino) {
+    free(cwd);
+    return x_strdup(pwd);
+  } else {
+    return cwd;
+  }
 }
 
 // Check whether s1 and s2 have the same executable name.
 bool
-same_executable_name(const char *s1, const char *s2)
+same_executable_name(const char* s1, const char* s2)
 {
 #ifdef _WIN32
-       bool eq = strcasecmp(s1, s2) == 0;
-       if (!eq) {
-               char *tmp = format("%s.exe", s2);
-               eq = strcasecmp(s1, tmp) == 0;
-               free(tmp);
-       }
-       return eq;
+  bool eq = strcasecmp(s1, s2) == 0;
+  if (!eq) {
+    char* tmp = format("%s.exe", s2);
+    eq = strcasecmp(s1, tmp) == 0;
+    free(tmp);
+  }
+  return eq;
 #else
-       return str_eq(s1, s2);
+  return str_eq(s1, s2);
 #endif
 }
 
 // Compute the length of the longest directory path that is common to two
 // paths. s1 is assumed to be the path to a directory.
 size_t
-common_dir_prefix_length(const char *s1, const char *s2)
-{
-       const char *p1 = s1;
-       const char *p2 = s2;
-
-       while (*p1 && *p2 && *p1 == *p2) {
-               ++p1;
-               ++p2;
-       }
-       while ((*p1 && *p1 != '/') || (*p2 && *p2 != '/')) {
-               p1--;
-               p2--;
-       }
-       if (!*p1 && !*p2 && p2 == s2 + 1) {
-               // Special case for s1 and s2 both being "/".
-               return 0;
-       }
-       return p1 - s1;
+common_dir_prefix_length(const char* s1, const char* s2)
+{
+  const char* p1 = s1;
+  const char* p2 = s2;
+
+  while (*p1 && *p2 && *p1 == *p2) {
+    ++p1;
+    ++p2;
+  }
+  while ((*p1 && *p1 != '/') || (*p2 && *p2 != '/')) {
+    p1--;
+    p2--;
+  }
+  if (!*p1 && !*p2 && p2 == s2 + 1) {
+    // Special case for s1 and s2 both being "/".
+    return 0;
+  }
+  return p1 - s1;
 }
 
 // Compute a relative path from from (an absolute path to a directory) to to (a
 // path). Assumes that both from and to are well-formed and canonical. Caller
 // frees.
-char *
-get_relative_path(const char *from, const char *to)
+char*
+get_relative_path(const char* from, const char* to)
 {
-       size_t common_prefix_len;
-       char *result;
+  size_t common_prefix_len;
+  char* result;
 
-       assert(from && is_absolute_path(from));
-       assert(to);
+  assert(from && is_absolute_path(from));
+  assert(to);
 
-       if (!*to || !is_absolute_path(to)) {
-               return x_strdup(to);
-       }
+  if (!*to || !is_absolute_path(to)) {
+    return x_strdup(to);
+  }
 
 #ifdef _WIN32
-       // Paths can be escaped by a slash for use with -isystem.
-       if (from[0] == '/') {
-               from++;
-       }
-       if (to[0] == '/') {
-               to++;
-       }
-       // Both paths are absolute, drop the drive letters.
-       assert(from[0] == to[0]); // Assume the same drive letter.
-       from += 2;
-       to += 2;
+  // Paths can be escaped by a slash for use with -isystem.
+  if (from[0] == '/') {
+    from++;
+  }
+  if (to[0] == '/') {
+    to++;
+  }
+  // Both paths are absolute, drop the drive letters.
+  assert(from[0] == to[0]); // Assume the same drive letter.
+  from += 2;
+  to += 2;
 #endif
 
-       result = x_strdup("");
-       common_prefix_len = common_dir_prefix_length(from, to);
-       if (common_prefix_len > 0 || !str_eq(from, "/")) {
-               const char *p;
-               for (p = from + common_prefix_len; *p; p++) {
-                       if (*p == '/') {
-                               reformat(&result, "../%s", result);
-                       }
-               }
-       }
-       if (strlen(to) > common_prefix_len) {
-               reformat(&result, "%s%s", result, to + common_prefix_len + 1);
-       }
-       for (int i = strlen(result) - 1; i >= 0 && result[i] == '/'; i--) {
-               result[i] = '\0';
-       }
-       if (str_eq(result, "")) {
-               free(result);
-               result = x_strdup(".");
-       }
-       return result;
+  result = x_strdup("");
+  common_prefix_len = common_dir_prefix_length(from, to);
+  if (common_prefix_len > 0 || !str_eq(from, "/")) {
+    const char* p;
+    for (p = from + common_prefix_len; *p; p++) {
+      if (*p == '/') {
+        reformat(&result, "../%s", result);
+      }
+    }
+  }
+  if (strlen(to) > common_prefix_len) {
+    reformat(&result, "%s%s", result, to + common_prefix_len + 1);
+  }
+  for (int i = strlen(result) - 1; i >= 0 && result[i] == '/'; i--) {
+    result[i] = '\0';
+  }
+  if (str_eq(result, "")) {
+    free(result);
+    result = x_strdup(".");
+  }
+  return result;
 }
 
 // Return whether path is absolute.
 bool
-is_absolute_path(const char *path)
+is_absolute_path(const charpath)
 {
 #ifdef _WIN32
-       return path[0] && path[1] == ':';
+  return path[0] && path[1] == ':';
 #else
-       return path[0] == '/';
+  return path[0] == '/';
 #endif
 }
 
 // Return whether the argument is a full path.
 bool
-is_full_path(const char *path)
+is_full_path(const charpath)
 {
-       if (strchr(path, '/')) {
-               return true;
-       }
+  if (strchr(path, '/')) {
+    return true;
+  }
 #ifdef _WIN32
-       if (strchr(path, '\\')) {
-               return true;
-       }
+  if (strchr(path, '\\')) {
+    return true;
+  }
 #endif
-       return false;
+  return false;
 }
 
-bool is_symlink(const char *path)
+bool
+is_symlink(const char* path)
 {
 #ifdef _WIN32
-       (void)path;
-       return false;
+  (void)path;
+  return false;
 #else
-       struct stat st;
-       return x_lstat(path, &st) == 0 && ((st.st_mode & S_IFMT) == S_IFLNK);
+  struct stat st;
+  return x_lstat(path, &st) == 0 && ((st.st_mode & S_IFMT) == S_IFLNK);
 #endif
 }
 
 // Update the modification time of a file in the cache to save it from LRU
 // cleanup.
 void
-update_mtime(const char *path)
+update_mtime(const charpath)
 {
 #ifdef HAVE_UTIMES
-       utimes(path, NULL);
+  utimes(path, NULL);
 #else
-       utime(path, NULL);
+  utime(path, NULL);
 #endif
 }
 
@@ -1486,294 +1497,299 @@ update_mtime(const char *path)
 void
 x_exit(int status)
 {
-       static bool first_time = true;
-       if (first_time) {
-               first_time = false;
-               exit(status);
-       } else {
-               _exit(status);
-       }
+  static bool first_time = true;
+  if (first_time) {
+    first_time = false;
+    exit(status);
+  } else {
+    _exit(status);
+  }
 }
 
 // Rename oldpath to newpath (deleting newpath).
 int
-x_rename(const char *oldpath, const char *newpath)
+x_rename(const char* oldpath, const char* newpath)
 {
 #ifndef _WIN32
-       return rename(oldpath, newpath);
+  return rename(oldpath, newpath);
 #else
-       // Windows' rename() refuses to overwrite an existing file.
-       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 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) &lp_msg_buf,
-                       0,
-                       NULL);
-
-               LPVOID lp_display_buf = (LPVOID) LocalAlloc(
-                       LMEM_ZEROINIT,
-                       (lstrlen((LPCTSTR) lp_msg_buf) + lstrlen((LPCTSTR) __FILE__) + 40)
-                       * sizeof(TCHAR));
-               _snprintf((LPTSTR) lp_display_buf,
-                         LocalSize(lp_display_buf) / sizeof(TCHAR),
-                         TEXT("%s failed with error %lu: %s"), __FILE__, dw,
-                         (const char *)lp_msg_buf);
-
-               cc_log("can't rename file %s to %s OS returned error: %s",
-                      oldpath, newpath, (char *) lp_display_buf);
-
-               LocalFree(lp_msg_buf);
-               LocalFree(lp_display_buf);
-               return -1;
-       } else {
-               return 0;
-       }
+  // Windows' rename() refuses to overwrite an existing file.
+  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 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)&lp_msg_buf,
+                  0,
+                  NULL);
+
+    LPVOID lp_display_buf = (LPVOID)LocalAlloc(
+      LMEM_ZEROINIT,
+      (lstrlen((LPCTSTR)lp_msg_buf) + lstrlen((LPCTSTR)__FILE__) + 40)
+        * sizeof(TCHAR));
+    _snprintf((LPTSTR)lp_display_buf,
+              LocalSize(lp_display_buf) / sizeof(TCHAR),
+              TEXT("%s failed with error %lu: %s"),
+              __FILE__,
+              dw,
+              (const char*)lp_msg_buf);
+
+    cc_log("can't rename file %s to %s OS returned error: %s",
+           oldpath,
+           newpath,
+           (char*)lp_display_buf);
+
+    LocalFree(lp_msg_buf);
+    LocalFree(lp_display_buf);
+    return -1;
+  } else {
+    return 0;
+  }
 #endif
 }
 
 // Remove path, NFS hazardous. Use only for temporary files that will not exist
 // on other systems. That is, the path should include tmp_string().
 int
-tmp_unlink(const char *path)
+tmp_unlink(const charpath)
 {
-       cc_log("Unlink %s", path);
-       int rc = unlink(path);
-       if (rc) {
-               cc_log("Unlink failed: %s", strerror(errno));
-       }
-       return rc;
+  cc_log("Unlink %s", path);
+  int rc = unlink(path);
+  if (rc) {
+    cc_log("Unlink failed: %s", strerror(errno));
+  }
+  return rc;
 }
 
 static int
-do_x_unlink(const char *path, bool log_failure)
-{
-       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;
-       if (x_rename(path, tmp_name) == -1) {
-               result = -1;
-               saved_errno = errno;
-               goto out;
-       }
-       if (unlink(tmp_name) == -1) {
-               // If it was released in a race, that's OK.
-               if (errno != ENOENT && errno != ESTALE) {
-                       result = -1;
-                       saved_errno = errno;
-               }
-       }
+do_x_unlink(const charpath, bool log_failure)
+{
+  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;
+  if (x_rename(path, tmp_name) == -1) {
+    result = -1;
+    saved_errno = errno;
+    goto out;
+  }
+  if (unlink(tmp_name) == -1) {
+    // If it was released in a race, that's OK.
+    if (errno != ENOENT && errno != ESTALE) {
+      result = -1;
+      saved_errno = errno;
+    }
+  }
 
 out:
-       if (result == 0 || log_failure) {
-               cc_log("Unlink %s via %s", path, tmp_name);
-               if (result != 0 && log_failure) {
-                       cc_log("x_unlink failed: %s", strerror(saved_errno));
-               }
-       }
-       free(tmp_name);
-       errno = saved_errno;
-       return result;
+  if (result == 0 || log_failure) {
+    cc_log("Unlink %s via %s", path, tmp_name);
+    if (result != 0 && log_failure) {
+      cc_log("x_unlink failed: %s", strerror(saved_errno));
+    }
+  }
+  free(tmp_name);
+  errno = saved_errno;
+  return result;
 }
 
 // Remove path, NFS safe, log both successes and failures.
 int
-x_unlink(const char *path)
+x_unlink(const charpath)
 {
-       return do_x_unlink(path, true);
+  return do_x_unlink(path, true);
 }
 
 // Remove path, NFS safe, only log successes.
 int
-x_try_unlink(const char *path)
+x_try_unlink(const charpath)
 {
-       return do_x_unlink(path, false);
+  return do_x_unlink(path, false);
 }
 
 #ifndef _WIN32
 // Like readlink() but returns the string or NULL on failure. Caller frees.
-char *
-x_readlink(const char *path)
-{
-       long maxlen = path_max(path);
-       char *buf = static_cast<char*>(x_malloc(maxlen));
-       ssize_t len = readlink(path, buf, maxlen-1);
-       if (len == -1) {
-               free(buf);
-               return NULL;
-       }
-       buf[len] = 0;
-       return buf;
+char*
+x_readlink(const charpath)
+{
+  long maxlen = path_max(path);
+  char* buf = static_cast<char*>(x_malloc(maxlen));
+  ssize_t len = readlink(path, buf, maxlen - 1);
+  if (len == -1) {
+    free(buf);
+    return NULL;
+  }
+  buf[len] = 0;
+  return buf;
 }
 #endif
 
 // Reads the content of a file. Size hint 0 means no hint. Returns true on
 // success, otherwise false.
 bool
-read_file(const char *path, size_t size_hint, char **data, size_t *size)
-{
-       if (size_hint == 0) {
-               struct stat st;
-               if (x_stat(path, &st) == 0) {
-                       size_hint = st.st_size;
-               }
-       }
-       size_hint = (size_hint < 1024) ? 1024 : size_hint;
-
-       int fd = open(path, O_RDONLY | O_BINARY);
-       if (fd == -1) {
-               return false;
-       }
-       size_t allocated = size_hint;
-       *data = static_cast<char*>(x_malloc(allocated));
-       int ret;
-       size_t pos = 0;
-       while (true) {
-               if (pos > allocated / 2) {
-                       allocated *= 2;
-                       *data = static_cast<char*>(x_realloc(*data, allocated));
-               }
-               ret = read(fd, *data + pos, allocated - pos);
-               if (ret == 0 || (ret == -1 && errno != EINTR)) {
-                       break;
-               }
-               if (ret > 0) {
-                       pos += ret;
-               }
-       }
-       close(fd);
-       if (ret == -1) {
-               cc_log("Failed reading %s", path);
-               free(*data);
-               *data = NULL;
-               return false;
-       }
-
-       *size = pos;
-       return true;
+read_file(const char* path, size_t size_hint, char** data, size_t* size)
+{
+  if (size_hint == 0) {
+    struct stat st;
+    if (x_stat(path, &st) == 0) {
+      size_hint = st.st_size;
+    }
+  }
+  size_hint = (size_hint < 1024) ? 1024 : size_hint;
+
+  int fd = open(path, O_RDONLY | O_BINARY);
+  if (fd == -1) {
+    return false;
+  }
+  size_t allocated = size_hint;
+  *data = static_cast<char*>(x_malloc(allocated));
+  int ret;
+  size_t pos = 0;
+  while (true) {
+    if (pos > allocated / 2) {
+      allocated *= 2;
+      *data = static_cast<char*>(x_realloc(*data, allocated));
+    }
+    ret = read(fd, *data + pos, allocated - pos);
+    if (ret == 0 || (ret == -1 && errno != EINTR)) {
+      break;
+    }
+    if (ret > 0) {
+      pos += ret;
+    }
+  }
+  close(fd);
+  if (ret == -1) {
+    cc_log("Failed reading %s", path);
+    free(*data);
+    *data = NULL;
+    return false;
+  }
+
+  *size = pos;
+  return true;
 }
 
 // Return the content (with NUL termination) of a text file, or NULL on error.
 // Caller frees. Size hint 0 means no hint.
-char *
-read_text_file(const char *path, size_t size_hint)
+char*
+read_text_file(const charpath, size_t size_hint)
 {
-       size_t size;
-       char *data;
-       if (read_file(path, size_hint, &data, &size)) {
-               data = static_cast<char*>(x_realloc(data, size + 1));
-               data[size] = '\0';
-               return data;
-       } else {
-               return NULL;
-       }
+  size_t size;
+  char* data;
+  if (read_file(path, size_hint, &data, &size)) {
+    data = static_cast<char*>(x_realloc(data, size + 1));
+    data[size] = '\0';
+    return data;
+  } else {
+    return NULL;
+  }
 }
 
 static bool
-expand_variable(const char **str, char **result, char **errmsg)
-{
-       assert(**str == '$');
-
-       bool curly;
-       const char *p = *str + 1;
-       if (*p == '{') {
-               curly = true;
-               ++p;
-       } else {
-               curly = false;
-       }
-
-       const char *q = p;
-       while (isalnum(*q) || *q == '_') {
-               ++q;
-       }
-       if (curly) {
-               if (*q != '}') {
-                       *errmsg = format("syntax error: missing '}' after \"%s\"", p);
-                       return false;
-               }
-       }
-
-       if (q == p) {
-               // Special case: don't consider a single $ the start of a variable.
-               reformat(result, "%s$", *result);
-               return true;
-       }
-
-       char *name = x_strndup(p, q - p);
-       const char *value = getenv(name);
-       if (!value) {
-               *errmsg = format("environment variable \"%s\" not set", name);
-               free(name);
-               return false;
-       }
-       reformat(result, "%s%s", *result, value);
-       if (!curly) {
-               --q;
-       }
-       *str = q;
-       free(name);
-       return true;
+expand_variable(const char** str, char** result, char** errmsg)
+{
+  assert(**str == '$');
+
+  bool curly;
+  const char* p = *str + 1;
+  if (*p == '{') {
+    curly = true;
+    ++p;
+  } else {
+    curly = false;
+  }
+
+  const char* q = p;
+  while (isalnum(*q) || *q == '_') {
+    ++q;
+  }
+  if (curly) {
+    if (*q != '}') {
+      *errmsg = format("syntax error: missing '}' after \"%s\"", p);
+      return false;
+    }
+  }
+
+  if (q == p) {
+    // Special case: don't consider a single $ the start of a variable.
+    reformat(result, "%s$", *result);
+    return true;
+  }
+
+  char* name = x_strndup(p, q - p);
+  const char* value = getenv(name);
+  if (!value) {
+    *errmsg = format("environment variable \"%s\" not set", name);
+    free(name);
+    return false;
+  }
+  reformat(result, "%s%s", *result, value);
+  if (!curly) {
+    --q;
+  }
+  *str = q;
+  free(name);
+  return true;
 }
 
 // Substitute all instances of $VAR or ${VAR}, where VAR is an environment
 // variable, in a string. Caller frees. If one of the environment variables
 // doesn't exist, NULL will be returned and *errmsg will be an appropriate
 // error message (caller frees).
-char *
-subst_env_in_string(const char *str, char **errmsg)
-{
-       assert(errmsg);
-       *errmsg = NULL;
-
-       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);
-                       if (!expand_variable(&q, &result, errmsg)) {
-                               free(result);
-                               return NULL;
-                       }
-                       p = q + 1;
-               }
-       }
-       reformat(&result, "%s%.*s", result, (int)(q - p), p);
-       return result;
+char*
+subst_env_in_string(const char* str, char** errmsg)
+{
+  assert(errmsg);
+  *errmsg = NULL;
+
+  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);
+      if (!expand_variable(&q, &result, errmsg)) {
+        free(result);
+        return NULL;
+      }
+      p = q + 1;
+    }
+  }
+  reformat(&result, "%s%.*s", result, (int)(q - p), p);
+  return result;
 }
 
 void
 set_cloexec_flag(int fd)
 {
 #ifndef _WIN32
-       int flags = fcntl(fd, F_GETFD, 0);
-       if (flags >= 0) {
-               fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
-       }
+  int flags = fcntl(fd, F_GETFD, 0);
+  if (flags >= 0) {
+    fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+  }
 #else
-       (void)fd;
+  (void)fd;
 #endif
 }
 
-double time_seconds(void)
+double
+time_seconds(void)
 {
 #ifdef HAVE_GETTIMEOFDAY
-       struct timeval tv;
-       gettimeofday(&tv, NULL);
-       return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
 #else
-       return (double)time(NULL);
+  return (double)time(NULL);
 #endif
 }
index ca4bbbe3d36d67087b1471c2e862a0d677477618..4cab44be6d4dc48a4f2e28c0281d6c7aa86c810a 100644 (file)
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 #include "framework.hpp"
+
 #include "util.hpp"
 
 #include <float.h>
 #include <math.h>
 #if defined(HAVE_TERMIOS_H)
-#define USE_COLOR
-#include <termios.h>
+#  define USE_COLOR
+#  include <termios.h>
 #endif
 
 static unsigned total_asserts;
 static unsigned total_tests;
 static unsigned total_suites;
 static unsigned failed_tests;
-static const char *current_suite;
-static const char *current_test;
-static char *dir_before_suite;
-static char *dir_before_test;
+static const charcurrent_suite;
+static const charcurrent_test;
+static chardir_before_suite;
+static chardir_before_test;
 static int verbose;
 
 static const char COLOR_END[] = "\x1b[m";
@@ -41,282 +42,309 @@ static const char COLOR_GREEN[] = "\x1b[1;32m";
 static const char COLOR_RED[] = "\x1b[1;31m";
 static char CONFIG_PATH_ENV[] = "CCACHE_CONFIG_PATH=/dev/null";
 
-#define COLOR(tty, color) ((tty) ? COLOR_ ## color : "")
+#define COLOR(tty, color) ((tty) ? COLOR_##color : "")
 
 static int
 is_tty(int fd)
 {
 #ifdef USE_COLOR
-       struct termios t;
-       return tcgetattr(fd, &t) == 0;
+  struct termios t;
+  return tcgetattr(fd, &t) == 0;
 #else
-       (void)fd;
-       return 0;
+  (void)fd;
+  return 0;
 #endif
 }
 
-static const char *
+static const char*
 plural_s(unsigned n)
 {
-       return n == 1 ? "" : "s";
+  return n == 1 ? "" : "s";
 }
 
 int
-cct_run(suite_fn *suites, int verbose_output)
+cct_run(suite_fnsuites, int verbose_output)
 {
-       suite_fn *suite;
-       int tty = is_tty(1);
+  suite_fn* suite;
+  int tty = is_tty(1);
 
-       x_unsetenv("GCC_COLORS"); // Avoid confusing argument processing tests.
-       verbose = verbose_output;
+  x_unsetenv("GCC_COLORS"); // Avoid confusing argument processing tests.
+  verbose = verbose_output;
 
-       for (suite = suites; *suite; suite++) {
-               unsigned test_index = 0;
-               while (true) {
-                       test_index = (*suite)(test_index + 1);
-                       if (test_index == 0) {
-                               // We have reached the end of the suite.
-                               break;
-                       }
-               }
-       }
+  for (suite = suites; *suite; suite++) {
+    unsigned test_index = 0;
+    while (true) {
+      test_index = (*suite)(test_index + 1);
+      if (test_index == 0) {
+        // We have reached the end of the suite.
+        break;
+      }
+    }
+  }
 
-       if (failed_tests == 0) {
-               printf("%sPASSED%s: %u assertion%s, %u test%s, %u suite%s\n",
-                      COLOR(tty, GREEN), COLOR(tty, END),
-                      total_asserts, plural_s(total_asserts),
-                      total_tests, plural_s(total_tests),
-                      total_suites, plural_s(total_suites));
-       } else {
-               printf("%sFAILED%s: %u test%s\n",
-                      COLOR(tty, RED), COLOR(tty, END),
-                      failed_tests, plural_s(failed_tests));
-       }
-       return failed_tests > 0 ? 1 : 0;
+  if (failed_tests == 0) {
+    printf("%sPASSED%s: %u assertion%s, %u test%s, %u suite%s\n",
+           COLOR(tty, GREEN),
+           COLOR(tty, END),
+           total_asserts,
+           plural_s(total_asserts),
+           total_tests,
+           plural_s(total_tests),
+           total_suites,
+           plural_s(total_suites));
+  } else {
+    printf("%sFAILED%s: %u test%s\n",
+           COLOR(tty, RED),
+           COLOR(tty, END),
+           failed_tests,
+           plural_s(failed_tests));
+  }
+  return failed_tests > 0 ? 1 : 0;
 }
 
 void
-cct_suite_begin(const char *name)
+cct_suite_begin(const charname)
 {
-       ++total_suites;
-       if (verbose) {
-               printf("=== SUITE: %s ===\n", name);
-       }
-       dir_before_suite = gnu_getcwd();
-       create_dir(name);
-       cct_chdir(name);
-       current_suite = name;
+  ++total_suites;
+  if (verbose) {
+    printf("=== SUITE: %s ===\n", name);
+  }
+  dir_before_suite = gnu_getcwd();
+  create_dir(name);
+  cct_chdir(name);
+  current_suite = name;
 }
 
 void
 cct_suite_end()
 {
-       cct_chdir(dir_before_suite);
-       free(dir_before_suite);
-       dir_before_suite = NULL;
+  cct_chdir(dir_before_suite);
+  free(dir_before_suite);
+  dir_before_suite = NULL;
 }
 
 void
-cct_test_begin(const char *name)
+cct_test_begin(const charname)
 {
-       ++total_tests;
-       if (verbose) {
-               printf("--- TEST: %s ---\n", name);
-       }
-       dir_before_test = gnu_getcwd();
-       create_dir(name);
-       cct_chdir(name);
-       current_test = name;
+  ++total_tests;
+  if (verbose) {
+    printf("--- TEST: %s ---\n", name);
+  }
+  dir_before_test = gnu_getcwd();
+  create_dir(name);
+  cct_chdir(name);
+  current_test = name;
 
-       putenv(CONFIG_PATH_ENV);
-       cc_reset();
+  putenv(CONFIG_PATH_ENV);
+  cc_reset();
 }
 
 void
 cct_test_end()
 {
-       if (dir_before_test) {
-               cct_chdir(dir_before_test);
-               free(dir_before_test);
-               dir_before_test = NULL;
-       }
+  if (dir_before_test) {
+    cct_chdir(dir_before_test);
+    free(dir_before_test);
+    dir_before_test = NULL;
+  }
 }
 
 void
-cct_check_passed(const char *file, int line, const char *what)
+cct_check_passed(const char* file, int line, const char* what)
 {
-       ++total_asserts;
-       if (verbose) {
-               printf("%s:%d: Passed assertion: %s\n", file, line, what);
-       }
+  ++total_asserts;
+  if (verbose) {
+    printf("%s:%d: Passed assertion: %s\n", file, line, what);
+  }
 }
 
 void
-cct_check_failed(const char *file, int line, const char *what,
-                 const char *expected, const char *actual)
+cct_check_failed(const char* file,
+                 int line,
+                 const char* what,
+                 const char* expected,
+                 const char* actual)
 {
-       ++total_asserts;
-       ++failed_tests;
-       fprintf(stderr, "%s:%d: Failed assertion:\n", file, line);
-       fprintf(stderr, "  Suite:      %s\n", current_suite);
-       fprintf(stderr, "  Test:       %s\n", current_test);
-       if (expected) {
-               fprintf(stderr, "  Expression: %s\n", what);
-               if (actual) {
-                       fprintf(stderr, "  Expected:   %s\n", expected);
-                       fprintf(stderr, "  Actual:     %s\n", actual);
-               } else {
-                       fprintf(stderr, "  Message:    %s\n", expected);
-               }
-       } else {
-               fprintf(stderr, "  Assertion:  %s\n", what);
-       }
-       fprintf(stderr, "\n");
+  ++total_asserts;
+  ++failed_tests;
+  fprintf(stderr, "%s:%d: Failed assertion:\n", file, line);
+  fprintf(stderr, "  Suite:      %s\n", current_suite);
+  fprintf(stderr, "  Test:       %s\n", current_test);
+  if (expected) {
+    fprintf(stderr, "  Expression: %s\n", what);
+    if (actual) {
+      fprintf(stderr, "  Expected:   %s\n", expected);
+      fprintf(stderr, "  Actual:     %s\n", actual);
+    } else {
+      fprintf(stderr, "  Message:    %s\n", expected);
+    }
+  } else {
+    fprintf(stderr, "  Assertion:  %s\n", what);
+  }
+  fprintf(stderr, "\n");
 }
 
 bool
-cct_check_double_eq(const char *file, int line, const char *expression,
-                    double expected, double actual)
+cct_check_double_eq(const char* file,
+                    int line,
+                    const char* expression,
+                    double expected,
+                    double actual)
 {
-       if (fabs(expected -  actual) < DBL_EPSILON) {
-               cct_check_passed(file, line, expression);
-               return true;
-       } else {
-               char *exp_str = format("%.1f", expected);
-               char *act_str = format("%.1f", actual);
-               cct_check_failed(file, line, expression, exp_str, act_str);
-               free(exp_str);
-               free(act_str);
-               return false;
-       }
+  if (fabs(expected - actual) < DBL_EPSILON) {
+    cct_check_passed(file, line, expression);
+    return true;
+  } else {
+    char* exp_str = format("%.1f", expected);
+    char* act_str = format("%.1f", actual);
+    cct_check_failed(file, line, expression, exp_str, act_str);
+    free(exp_str);
+    free(act_str);
+    return false;
+  }
 }
 bool
-cct_check_int_eq(const char *file, int line, const char *expression,
-                 int64_t expected, int64_t actual)
+cct_check_int_eq(const char* file,
+                 int line,
+                 const char* expression,
+                 int64_t expected,
+                 int64_t actual)
 {
-       if (expected == actual) {
-               cct_check_passed(file, line, expression);
-               return true;
-       } else {
+  if (expected == actual) {
+    cct_check_passed(file, line, expression);
+    return true;
+  } else {
 #if defined(HAVE_LONG_LONG) && !defined(__MINGW32__)
-               char *exp_str = format("%lld", (long long)expected);
-               char *act_str = format("%lld", (long long)actual);
+    char* exp_str = format("%lld", (long long)expected);
+    char* act_str = format("%lld", (long long)actual);
 #else
-               char *exp_str = format("%ld", (long)expected);
-               char *act_str = format("%ld", (long)actual);
+    char* exp_str = format("%ld", (long)expected);
+    char* act_str = format("%ld", (long)actual);
 #endif
-               cct_check_failed(file, line, expression, exp_str, act_str);
-               free(exp_str);
-               free(act_str);
-               return false;
-       }
+    cct_check_failed(file, line, expression, exp_str, act_str);
+    free(exp_str);
+    free(act_str);
+    return false;
+  }
 }
 
-bool cct_check_data_eq(const char *file, int line, const char *expression,
-                       const uint8_t *expected, const uint8_t *actual,
-                       size_t size)
+bool
+cct_check_data_eq(const char* file,
+                  int line,
+                  const char* expression,
+                  const uint8_t* expected,
+                  const uint8_t* actual,
+                  size_t size)
 {
-       if (memcmp(actual, expected, size) == 0) {
-               cct_check_passed(file, line, expression);
-               return true;
-       } else {
-               char *exp_str = static_cast<char*>(x_malloc(2 * size + 1));
-               char *act_str = static_cast<char*>(x_malloc(2 * size + 1));
-               format_hex(expected, size, exp_str);
-               format_hex(actual, size, act_str);
-               cct_check_failed(file, line, expression, exp_str, act_str);
-               free(exp_str);
-               free(act_str);
-               return false;
-       }
+  if (memcmp(actual, expected, size) == 0) {
+    cct_check_passed(file, line, expression);
+    return true;
+  } else {
+    char* exp_str = static_cast<char*>(x_malloc(2 * size + 1));
+    char* act_str = static_cast<char*>(x_malloc(2 * size + 1));
+    format_hex(expected, size, exp_str);
+    format_hex(actual, size, act_str);
+    cct_check_failed(file, line, expression, exp_str, act_str);
+    free(exp_str);
+    free(act_str);
+    return false;
+  }
 }
 
 bool
-cct_check_str_eq(const char *file, int line, const char *expression,
-                 const char *expected, const char *actual,
-                 bool free1, bool free2)
+cct_check_str_eq(const char* file,
+                 int line,
+                 const char* expression,
+                 const char* expected,
+                 const char* actual,
+                 bool free1,
+                 bool free2)
 {
-       bool result;
+  bool result;
 
-       if (expected && actual && str_eq(actual, expected)) {
-               cct_check_passed(file, line, expression);
-               result = true;
-       } else {
-               char *exp_str = expected ? format("\"%s\"", expected) : x_strdup("(null)");
-               char *act_str = actual ? format("\"%s\"", actual) : x_strdup("(null)");
-               cct_check_failed(file, line, expression, exp_str, act_str);
-               free(exp_str);
-               free(act_str);
-               result = false;
-       }
+  if (expected && actual && str_eq(actual, expected)) {
+    cct_check_passed(file, line, expression);
+    result = true;
+  } else {
+    char* exp_str = expected ? format("\"%s\"", expected) : x_strdup("(null)");
+    char* act_str = actual ? format("\"%s\"", actual) : x_strdup("(null)");
+    cct_check_failed(file, line, expression, exp_str, act_str);
+    free(exp_str);
+    free(act_str);
+    result = false;
+  }
 
-       if (free1) {
-               free(const_cast<char*>(expected));
-       }
-       if (free2) {
-               free(const_cast<char*>(actual));
-       }
-       return result;
+  if (free1) {
+    free(const_cast<char*>(expected));
+  }
+  if (free2) {
+    free(const_cast<char*>(actual));
+  }
+  return result;
 }
 
 bool
-cct_check_args_eq(const char *file, int line, const char *expression,
-                  const struct args *expected, const struct args *actual,
-                  bool free1, bool free2)
+cct_check_args_eq(const char* file,
+                  int line,
+                  const char* expression,
+                  const struct args* expected,
+                  const struct args* actual,
+                  bool free1,
+                  bool free2)
 {
-       bool result;
+  bool result;
 
-       if (expected && actual && args_equal(actual, expected)) {
-               cct_check_passed(file, line, expression);
-               result = true;
-       } else {
-               char *exp_str = expected ? args_to_string(expected) : x_strdup("(null)");
-               char *act_str = actual ? args_to_string(actual) : x_strdup("(null)");
-               cct_check_failed(file, line, expression, exp_str, act_str);
-               free(exp_str);
-               free(act_str);
-               result = false;
-       }
+  if (expected && actual && args_equal(actual, expected)) {
+    cct_check_passed(file, line, expression);
+    result = true;
+  } else {
+    char* exp_str = expected ? args_to_string(expected) : x_strdup("(null)");
+    char* act_str = actual ? args_to_string(actual) : x_strdup("(null)");
+    cct_check_failed(file, line, expression, exp_str, act_str);
+    free(exp_str);
+    free(act_str);
+    result = false;
+  }
 
-       if (free1) {
-               args_free(const_cast<struct args*>(expected));
-       }
-       if (free2) {
-               args_free(const_cast<struct args*>(actual));
-       }
-       return result;
+  if (free1) {
+    args_free(const_cast<struct args*>(expected));
+  }
+  if (free2) {
+    args_free(const_cast<struct args*>(actual));
+  }
+  return result;
 }
 
 void
-cct_chdir(const char *path)
+cct_chdir(const charpath)
 {
-       if (chdir(path) != 0) {
-               fprintf(stderr, "chdir: %s: %s", path, strerror(errno));
-               abort();
-       }
+  if (chdir(path) != 0) {
+    fprintf(stderr, "chdir: %s: %s", path, strerror(errno));
+    abort();
+  }
 }
 
 void
-cct_wipe(const char *path)
+cct_wipe(const charpath)
 {
-       // TODO: rewrite using traverse().
+  // TODO: rewrite using traverse().
 #ifndef __MINGW32__
-       char *command = format("rm -rf %s", path);
+  char* command = format("rm -rf %s", path);
 #else
-       char *command = format("rd /s /q %s", path);
+  char* command = format("rd /s /q %s", path);
 #endif
-       if (system(command) != 0) {
-               perror(command);
-       }
-       free(command);
+  if (system(command) != 0) {
+    perror(command);
+  }
+  free(command);
 }
 
 void
-cct_create_fresh_dir(const char *path)
+cct_create_fresh_dir(const charpath)
 {
-       cct_wipe(path);
-       if (mkdir(path, 0777) != 0) {
-               fprintf(stderr, "mkdir: %s: %s", path, strerror(errno));
-               abort();
-       }
+  cct_wipe(path);
+  if (mkdir(path, 0777) != 0) {
+    fprintf(stderr, "mkdir: %s: %s", path, strerror(errno));
+    abort();
+  }
 }
index 77034410125e6f4f1fdf0cca9fdb7af948129ecd..f97a71d8aa96db1e06fd7e9e4246bb2951f57532 100644 (file)
 
 // ============================================================================
 
-#define TEST_SUITE(name) \
-       unsigned suite_##name(unsigned _start_point); \
-       unsigned suite_##name(unsigned _start_point) \
-       { \
-               unsigned _test_counter = 0; \
-               cct_suite_begin(#name); \
-               { \
-                       // Empty due to macro trickery.
-
-#define TEST(name) \
-                       cct_test_end(); \
-               } \
-               ++_test_counter; \
-               { static int name = 0; (void)name; /* Verify test name. */ } \
-               if (_test_counter >= _start_point) { \
-                       cct_test_begin(#name);
-
-#define TEST_SUITE_END \
-                       cct_test_end(); \
-               } \
-               cct_suite_end(); \
-               return 0; /* We have reached the end. */ \
-       }
+#define TEST_SUITE(name)                                                       \
+  unsigned suite_##name(unsigned _start_point);                                \
+  unsigned suite_##name(unsigned _start_point)                                 \
+  {                                                                            \
+    unsigned _test_counter = 0;                                                \
+    cct_suite_begin(#name);                                                    \
+    {                                                                          \
+      // Empty due to macro trickery.
+
+#define TEST(name)                                                             \
+  cct_test_end();                                                              \
+  }                                                                            \
+  ++_test_counter;                                                             \
+  {                                                                            \
+    static int name = 0;                                                       \
+    (void)name; /* Verify test name. */                                        \
+  }                                                                            \
+  if (_test_counter >= _start_point) {                                         \
+    cct_test_begin(#name);
+
+#define TEST_SUITE_END                                                         \
+  cct_test_end();                                                              \
+  }                                                                            \
+  cct_suite_end();                                                             \
+  return 0; /* We have reached the end. */                                     \
+  }
 
 // ============================================================================
 
-#define CHECKM(assertion, message) \
-       do { \
-               if ((assertion)) { \
-                       cct_check_passed(__FILE__, __LINE__, #assertion); \
-               } else { \
-                       cct_check_failed(__FILE__, __LINE__, #assertion, (message), NULL); \
-                       cct_test_end(); \
-                       cct_suite_end(); \
-                       return _test_counter; \
-               } \
-       } while (false)
-
-#define CHECK(assertion) \
-       CHECKM(assertion, NULL)
-
-#define CHECK_POINTER_EQ_BASE(t, e, a, f1, f2) \
-       do { \
-               if (!cct_check_##t##_eq(__FILE__, __LINE__, #a, (e), (a), (f1), (f2))) { \
-                       cct_test_end(); \
-                       cct_suite_end(); \
-                       return _test_counter; \
-               } \
-       } while (false)
+#define CHECKM(assertion, message)                                             \
+  do {                                                                         \
+    if ((assertion)) {                                                         \
+      cct_check_passed(__FILE__, __LINE__, #assertion);                        \
+    } else {                                                                   \
+      cct_check_failed(__FILE__, __LINE__, #assertion, (message), NULL);       \
+      cct_test_end();                                                          \
+      cct_suite_end();                                                         \
+      return _test_counter;                                                    \
+    }                                                                          \
+  } while (false)
+
+#define CHECK(assertion) CHECKM(assertion, NULL)
+
+#define CHECK_POINTER_EQ_BASE(t, e, a, f1, f2)                                 \
+  do {                                                                         \
+    if (!cct_check_##t##_eq(__FILE__, __LINE__, #a, (e), (a), (f1), (f2))) {   \
+      cct_test_end();                                                          \
+      cct_suite_end();                                                         \
+      return _test_counter;                                                    \
+    }                                                                          \
+  } while (false)
 
 // ============================================================================
 
-#define CHECK_INT_EQ(expected, actual) \
-       do { \
-               if (!cct_check_int_eq(__FILE__, __LINE__, #actual, (expected), \
-                                     (actual))) { \
-                       cct_test_end(); \
-                       cct_suite_end(); \
-                       return _test_counter; \
-               } \
-       } while (false)
+#define CHECK_INT_EQ(expected, actual)                                         \
+  do {                                                                         \
+    if (!cct_check_int_eq(                                                     \
+          __FILE__, __LINE__, #actual, (expected), (actual))) {                \
+      cct_test_end();                                                          \
+      cct_suite_end();                                                         \
+      return _test_counter;                                                    \
+    }                                                                          \
+  } while (false)
 
 // ============================================================================
 
-#define CHECK_DOUBLE_EQ(expected, actual) \
-       do { \
-               if (!cct_check_double_eq(__FILE__, __LINE__, #actual, (expected), \
-                                        (actual))) { \
-                       cct_test_end(); \
-                       cct_suite_end(); \
-                       return _test_counter; \
-               } \
-       } while (false)
+#define CHECK_DOUBLE_EQ(expected, actual)                                      \
+  do {                                                                         \
+    if (!cct_check_double_eq(                                                  \
+          __FILE__, __LINE__, #actual, (expected), (actual))) {                \
+      cct_test_end();                                                          \
+      cct_suite_end();                                                         \
+      return _test_counter;                                                    \
+    }                                                                          \
+  } while (false)
 
 // ============================================================================
 
-#define CHECK_DATA_EQ(expected, actual, size) \
-       do { \
-               if (!cct_check_data_eq(__FILE__, __LINE__, #actual, (expected), \
-                                     (actual), size)) { \
-                       cct_test_end(); \
-                       cct_suite_end(); \
-                       return _test_counter; \
-               } \
-       } while (false)
+#define CHECK_DATA_EQ(expected, actual, size)                                  \
+  do {                                                                         \
+    if (!cct_check_data_eq(                                                    \
+          __FILE__, __LINE__, #actual, (expected), (actual), size)) {          \
+      cct_test_end();                                                          \
+      cct_suite_end();                                                         \
+      return _test_counter;                                                    \
+    }                                                                          \
+  } while (false)
 
 // ============================================================================
 
-#define CHECK_STR_EQ(expected, actual) \
-       CHECK_POINTER_EQ_BASE(str, expected, actual, false, false)
+#define CHECK_STR_EQ(expected, actual)                                         \
+  CHECK_POINTER_EQ_BASE(str, expected, actual, false, false)
 
-#define CHECK_STR_EQ_FREE1(expected, actual) \
-       CHECK_POINTER_EQ_BASE(str, expected, actual, true, false)
+#define CHECK_STR_EQ_FREE1(expected, actual)                                   \
+  CHECK_POINTER_EQ_BASE(str, expected, actual, true, false)
 
-#define CHECK_STR_EQ_FREE2(expected, actual) \
-       CHECK_POINTER_EQ_BASE(str, expected, actual, false, true)
+#define CHECK_STR_EQ_FREE2(expected, actual)                                   \
+  CHECK_POINTER_EQ_BASE(str, expected, actual, false, true)
 
-#define CHECK_STR_EQ_FREE12(expected, actual) \
-       CHECK_POINTER_EQ_BASE(str, expected, actual, true, true)
+#define CHECK_STR_EQ_FREE12(expected, actual)                                  \
+  CHECK_POINTER_EQ_BASE(str, expected, actual, true, true)
 
 // ============================================================================
 
-#define CHECK_ARGS_EQ(expected, actual) \
-       CHECK_POINTER_EQ_BASE(args, expected, actual, false, false)
+#define CHECK_ARGS_EQ(expected, actual)                                        \
+  CHECK_POINTER_EQ_BASE(args, expected, actual, false, false)
 
-#define CHECK_ARGS_EQ_FREE1(expected, actual) \
-       CHECK_POINTER_EQ_BASE(args, expected, actual, true, false)
+#define CHECK_ARGS_EQ_FREE1(expected, actual)                                  \
+  CHECK_POINTER_EQ_BASE(args, expected, actual, true, false)
 
-#define CHECK_ARGS_EQ_FREE2(expected, actual) \
-       CHECK_POINTER_EQ_BASE(args, expected, actual, false, true)
+#define CHECK_ARGS_EQ_FREE2(expected, actual)                                  \
+  CHECK_POINTER_EQ_BASE(args, expected, actual, false, true)
 
-#define CHECK_ARGS_EQ_FREE12(expected, actual) \
-       CHECK_POINTER_EQ_BASE(args, expected, actual, true, true)
+#define CHECK_ARGS_EQ_FREE12(expected, actual)                                 \
+  CHECK_POINTER_EQ_BASE(args, expected, actual, true, true)
 
 // ============================================================================
 
 typedef unsigned (*suite_fn)(unsigned);
-int cct_run(suite_fn *suites, int verbose);
+int cct_run(suite_fnsuites, int verbose);
 
-void cct_suite_begin(const char *name);
+void cct_suite_begin(const charname);
 void cct_suite_end(void);
-void cct_test_begin(const char *name);
+void cct_test_begin(const charname);
 void cct_test_end(void);
-void cct_check_passed(const char *file, int line, const char *assertion);
-void cct_check_failed(const char *file, int line, const char *assertion,
-                      const char *expected, const char *actual);
-bool cct_check_double_eq(const char *file, int line, const char *expression,
-                         double expected, double actual);
-bool cct_check_int_eq(const char *file, int line, const char *expression,
-                      int64_t expected, int64_t actual);
-bool cct_check_data_eq(const char *file, int line, const char *expression,
-                       const uint8_t *expected, const uint8_t *actual, size_t size);
-bool cct_check_str_eq(const char *file, int line, const char *expression,
-                      const char *expected, const char *actual,
-                      bool free1, bool free2);
-bool cct_check_args_eq(const char *file, int line, const char *expression,
-                       const struct args *expected, const struct args *actual,
-                       bool free1, bool free2);
-void cct_chdir(const char *path);
-void cct_wipe(const char *path);
-void cct_create_fresh_dir(const char *path);
+void cct_check_passed(const char* file, int line, const char* assertion);
+void cct_check_failed(const char* file,
+                      int line,
+                      const char* assertion,
+                      const char* expected,
+                      const char* actual);
+bool cct_check_double_eq(const char* file,
+                         int line,
+                         const char* expression,
+                         double expected,
+                         double actual);
+bool cct_check_int_eq(const char* file,
+                      int line,
+                      const char* expression,
+                      int64_t expected,
+                      int64_t actual);
+bool cct_check_data_eq(const char* file,
+                       int line,
+                       const char* expression,
+                       const uint8_t* expected,
+                       const uint8_t* actual,
+                       size_t size);
+bool cct_check_str_eq(const char* file,
+                      int line,
+                      const char* expression,
+                      const char* expected,
+                      const char* actual,
+                      bool free1,
+                      bool free2);
+bool cct_check_args_eq(const char* file,
+                       int line,
+                       const char* expression,
+                       const struct args* expected,
+                       const struct args* actual,
+                       bool free1,
+                       bool free2);
+void cct_chdir(const char* path);
+void cct_wipe(const char* path);
+void cct_create_fresh_dir(const char* path);
index 9dbc6648f6936bf529b5ba70614ce30916bc209c..615044d9bc19950728f04d0e5f3a4e81dcd28721 100644 (file)
 
 #include "framework.hpp"
 #ifdef HAVE_GETOPT_LONG
-#include <getopt.h>
+#  include <getopt.h>
 #else
-#include "../src/third_party/getopt_long.h"
+#  include "../src/third_party/getopt_long.h"
 #endif
 
-#define SUITE(name) unsigned suite_ ## name(unsigned);
+#define SUITE(name) unsigned suite_##name(unsigned);
 #include "suites.hpp"
 #undef SUITE
 
 static const char USAGE_TEXT[] =
-       "Usage:\n"
-       "    test [options]\n"
-       "\n"
-       "Options:\n"
-       "    -h, --help      print this help text\n"
-       "    -v, --verbose   enable verbose logging of tests\n";
+  "Usage:\n"
+  "    test [options]\n"
+  "\n"
+  "Options:\n"
+  "    -h, --help      print this help text\n"
+  "    -v, --verbose   enable verbose logging of tests\n";
 
 int
-main(int argc, char **argv)
+main(int argc, char** argv)
 {
-       suite_fn suites[] = {
-#define SUITE(name) &suite_ ## name,
+  suite_fn suites[] = {
+#define SUITE(name) &suite_##name,
 #include "suites.hpp"
 #undef SUITE
-               NULL
-       };
-       static const struct option options[] = {
-               {"help", no_argument, NULL, 'h'},
-               {"verbose", no_argument, NULL, 'v'},
-               {NULL, 0, NULL, 0}
-       };
-       int verbose = 0;
-       int c;
-       char *testdir, *dir_before;
-       int result;
+    NULL};
+  static const struct option options[] = {{"help", no_argument, NULL, 'h'},
+                                          {"verbose", no_argument, NULL, 'v'},
+                                          {NULL, 0, NULL, 0}};
+  int verbose = 0;
+  int c;
+  char *testdir, *dir_before;
+  int result;
 
 #ifdef _WIN32
-       putenv("CCACHE_DETECT_SHEBANG=1");
+  putenv("CCACHE_DETECT_SHEBANG=1");
 #endif
 
-       while ((c = getopt_long(argc, argv, "hv", options, NULL)) != -1) {
-               switch (c) {
-               case 'h':
-                       fprintf(stdout, USAGE_TEXT);
-                       return 0;
+  while ((c = getopt_long(argc, argv, "hv", options, NULL)) != -1) {
+    switch (c) {
+    case 'h':
+      fprintf(stdout, USAGE_TEXT);
+      return 0;
 
-               case 'v':
-                       verbose = 1;
-                       break;
+    case 'v':
+      verbose = 1;
+      break;
 
-               default:
-                       fprintf(stderr, USAGE_TEXT);
-                       return 1;
-               }
-       }
+    default:
+      fprintf(stderr, USAGE_TEXT);
+      return 1;
+    }
+  }
 
-       testdir = format("testdir.%d", (int)getpid());
-       cct_create_fresh_dir(testdir);
-       dir_before = gnu_getcwd();
-       cct_chdir(testdir);
-       result = cct_run(suites, verbose);
-       if (result == 0) {
-               cct_chdir(dir_before);
-               cct_wipe(testdir);
-       }
-       free(testdir);
-       free(dir_before);
-       return result;
+  testdir = format("testdir.%d", (int)getpid());
+  cct_create_fresh_dir(testdir);
+  dir_before = gnu_getcwd();
+  cct_chdir(testdir);
+  result = cct_run(suites, verbose);
+  if (result == 0) {
+    cct_chdir(dir_before);
+    cct_wipe(testdir);
+  }
+  free(testdir);
+  free(dir_before);
+  return result;
 }
index 551290954d8c679482b22717edd607350029e0c4..d46bfa661e61cfb9091d0f065ab52c298e1c41b0 100644 (file)
@@ -26,190 +26,190 @@ TEST_SUITE(args)
 
 TEST(args_init_empty)
 {
-       struct args *args = args_init(0, NULL);
-       CHECK(args);
-       CHECK_INT_EQ(0, args->argc);
-       CHECK(!args->argv[0]);
-       args_free(args);
+  struct args* args = args_init(0, NULL);
+  CHECK(args);
+  CHECK_INT_EQ(0, args->argc);
+  CHECK(!args->argv[0]);
+  args_free(args);
 }
 
 TEST(args_init_populated)
 {
-       const char *argv[] = {"first", "second"};
-       struct args *args = args_init(2, argv);
-       CHECK(args);
-       CHECK_INT_EQ(2, args->argc);
-       CHECK_STR_EQ("first", args->argv[0]);
-       CHECK_STR_EQ("second", args->argv[1]);
-       CHECK(!args->argv[2]);
-       args_free(args);
+  const char* argv[] = {"first", "second"};
+  struct args* args = args_init(2, argv);
+  CHECK(args);
+  CHECK_INT_EQ(2, args->argc);
+  CHECK_STR_EQ("first", args->argv[0]);
+  CHECK_STR_EQ("second", args->argv[1]);
+  CHECK(!args->argv[2]);
+  args_free(args);
 }
 
 TEST(args_init_from_string)
 {
-       struct args *args = args_init_from_string("first second\tthird\nfourth");
-       CHECK(args);
-       CHECK_INT_EQ(4, args->argc);
-       CHECK_STR_EQ("first", args->argv[0]);
-       CHECK_STR_EQ("second", args->argv[1]);
-       CHECK_STR_EQ("third", args->argv[2]);
-       CHECK_STR_EQ("fourth", args->argv[3]);
-       CHECK(!args->argv[4]);
-       args_free(args);
+  struct args* args = args_init_from_string("first second\tthird\nfourth");
+  CHECK(args);
+  CHECK_INT_EQ(4, args->argc);
+  CHECK_STR_EQ("first", args->argv[0]);
+  CHECK_STR_EQ("second", args->argv[1]);
+  CHECK_STR_EQ("third", args->argv[2]);
+  CHECK_STR_EQ("fourth", args->argv[3]);
+  CHECK(!args->argv[4]);
+  args_free(args);
 }
 
 TEST(args_init_from_gcc_atfile)
 {
-       struct args *args;
-       const char *argtext =
-               "first\rsec\\\tond\tthi\\\\rd\nfourth  \tfif\\ th \"si'x\\\" th\""
-               " 'seve\nth'\\";
-
-       create_file("gcc_atfile", argtext);
-
-       args = args_init_from_gcc_atfile("gcc_atfile");
-       CHECK(args);
-       CHECK_INT_EQ(7, args->argc);
-       CHECK_STR_EQ("first", args->argv[0]);
-       CHECK_STR_EQ("sec\tond", args->argv[1]);
-       CHECK_STR_EQ("thi\\rd", args->argv[2]);
-       CHECK_STR_EQ("fourth", args->argv[3]);
-       CHECK_STR_EQ("fif th", args->argv[4]);
-       CHECK_STR_EQ("si'x\" th", args->argv[5]);
+  struct args* args;
+  const char* argtext =
+    "first\rsec\\\tond\tthi\\\\rd\nfourth  \tfif\\ th \"si'x\\\" th\""
+    " 'seve\nth'\\";
+
+  create_file("gcc_atfile", argtext);
+
+  args = args_init_from_gcc_atfile("gcc_atfile");
+  CHECK(args);
+  CHECK_INT_EQ(7, args->argc);
+  CHECK_STR_EQ("first", args->argv[0]);
+  CHECK_STR_EQ("sec\tond", args->argv[1]);
+  CHECK_STR_EQ("thi\\rd", args->argv[2]);
+  CHECK_STR_EQ("fourth", args->argv[3]);
+  CHECK_STR_EQ("fif th", args->argv[4]);
+  CHECK_STR_EQ("si'x\" th", args->argv[5]);
 #ifndef _WIN32
-       CHECK_STR_EQ("seve\nth", args->argv[6]);
+  CHECK_STR_EQ("seve\nth", args->argv[6]);
 #else
-       CHECK_STR_EQ("seve\r\nth", args->argv[6]);
+  CHECK_STR_EQ("seve\r\nth", args->argv[6]);
 #endif
-       CHECK(!args->argv[7]);
-       args_free(args);
+  CHECK(!args->argv[7]);
+  args_free(args);
 }
 
 TEST(args_copy)
 {
-       struct args *args1 = args_init_from_string("foo");
-       struct args *args2 = args_copy(args1);
-       CHECK_ARGS_EQ_FREE12(args1, args2);
+  struct args* args1 = args_init_from_string("foo");
+  struct args* args2 = args_copy(args1);
+  CHECK_ARGS_EQ_FREE12(args1, args2);
 }
 
 TEST(args_add)
 {
-       struct args *args = args_init_from_string("first");
-       CHECK_INT_EQ(1, args->argc);
-       args_add(args, "second");
-       CHECK_INT_EQ(2, args->argc);
-       CHECK_STR_EQ("second", args->argv[1]);
-       CHECK(!args->argv[2]);
-       args_free(args);
+  struct args* args = args_init_from_string("first");
+  CHECK_INT_EQ(1, args->argc);
+  args_add(args, "second");
+  CHECK_INT_EQ(2, args->argc);
+  CHECK_STR_EQ("second", args->argv[1]);
+  CHECK(!args->argv[2]);
+  args_free(args);
 }
 
 TEST(args_extend)
 {
-       struct args *args1 = args_init_from_string("first");
-       struct args *args2 = args_init_from_string("second third");
-       CHECK_INT_EQ(1, args1->argc);
-       args_extend(args1, args2);
-       CHECK_INT_EQ(3, args1->argc);
-       CHECK_STR_EQ("second", args1->argv[1]);
-       CHECK_STR_EQ("third", args1->argv[2]);
-       CHECK(!args1->argv[3]);
-       args_free(args1);
-       args_free(args2);
+  struct args* args1 = args_init_from_string("first");
+  struct args* args2 = args_init_from_string("second third");
+  CHECK_INT_EQ(1, args1->argc);
+  args_extend(args1, args2);
+  CHECK_INT_EQ(3, args1->argc);
+  CHECK_STR_EQ("second", args1->argv[1]);
+  CHECK_STR_EQ("third", args1->argv[2]);
+  CHECK(!args1->argv[3]);
+  args_free(args1);
+  args_free(args2);
 }
 
 TEST(args_pop)
 {
-       struct args *args = args_init_from_string("first second third");
-       args_pop(args, 2);
-       CHECK_INT_EQ(1, args->argc);
-       CHECK_STR_EQ("first", args->argv[0]);
-       CHECK(!args->argv[1]);
-       args_free(args);
+  struct args* args = args_init_from_string("first second third");
+  args_pop(args, 2);
+  CHECK_INT_EQ(1, args->argc);
+  CHECK_STR_EQ("first", args->argv[0]);
+  CHECK(!args->argv[1]);
+  args_free(args);
 }
 
 TEST(args_set)
 {
-       struct args *args = args_init_from_string("first second third");
-       args_set(args, 1, "2nd");
-       CHECK_INT_EQ(3, args->argc);
-       CHECK_STR_EQ("first", args->argv[0]);
-       CHECK_STR_EQ("2nd", args->argv[1]);
-       CHECK_STR_EQ("third", args->argv[2]);
-       CHECK(!args->argv[3]);
-       args_free(args);
+  struct args* args = args_init_from_string("first second third");
+  args_set(args, 1, "2nd");
+  CHECK_INT_EQ(3, args->argc);
+  CHECK_STR_EQ("first", args->argv[0]);
+  CHECK_STR_EQ("2nd", args->argv[1]);
+  CHECK_STR_EQ("third", args->argv[2]);
+  CHECK(!args->argv[3]);
+  args_free(args);
 }
 
 TEST(args_remove_first)
 {
-       struct args *args1 = args_init_from_string("first second third");
-       struct args *args2 = args_init_from_string("second third");
-       args_remove_first(args1);
-       CHECK_ARGS_EQ_FREE12(args1, args2);
+  struct args* args1 = args_init_from_string("first second third");
+  struct args* args2 = args_init_from_string("second third");
+  args_remove_first(args1);
+  CHECK_ARGS_EQ_FREE12(args1, args2);
 }
 
 TEST(args_add_prefix)
 {
-       struct args *args1 = args_init_from_string("second third");
-       struct args *args2 = args_init_from_string("first second third");
-       args_add_prefix(args1, "first");
-       CHECK_ARGS_EQ_FREE12(args1, args2);
+  struct args* args1 = args_init_from_string("second third");
+  struct args* args2 = args_init_from_string("first second third");
+  args_add_prefix(args1, "first");
+  CHECK_ARGS_EQ_FREE12(args1, args2);
 }
 
 TEST(args_strip)
 {
-       struct args *args1 = args_init_from_string("first xsecond third xfourth");
-       struct args *args2 = args_init_from_string("first third");
-       args_strip(args1, "x");
-       CHECK_ARGS_EQ_FREE12(args1, args2);
+  struct args* args1 = args_init_from_string("first xsecond third xfourth");
+  struct args* args2 = args_init_from_string("first third");
+  args_strip(args1, "x");
+  CHECK_ARGS_EQ_FREE12(args1, args2);
 }
 
 TEST(args_to_string)
 {
-       struct args *args = args_init_from_string("first second");
-       CHECK_STR_EQ_FREE2("first second", args_to_string(args));
-       args_free(args);
+  struct args* args = args_init_from_string("first second");
+  CHECK_STR_EQ_FREE2("first second", args_to_string(args));
+  args_free(args);
 }
 
 TEST(args_insert)
 {
-       struct args *args = args_init_from_string("first second third fourth fifth");
-
-       struct args *src1 = args_init_from_string("alpha beta gamma");
-       struct args *src2 = args_init_from_string("one");
-       struct args *src3 = args_init_from_string("");
-       struct args *src4 = args_init_from_string("alpha beta gamma");
-       struct args *src5 = args_init_from_string("one");
-       struct args *src6 = args_init_from_string("");
-
-       args_insert(args, 2, src1, true);
-       CHECK_STR_EQ_FREE2("first second alpha beta gamma fourth fifth",
-                          args_to_string(args));
-       CHECK_INT_EQ(7, args->argc);
-       args_insert(args, 2, src2, true);
-       CHECK_STR_EQ_FREE2("first second one beta gamma fourth fifth",
-                          args_to_string(args));
-       CHECK_INT_EQ(7, args->argc);
-       args_insert(args, 2, src3, true);
-       CHECK_STR_EQ_FREE2("first second beta gamma fourth fifth",
-                          args_to_string(args));
-       CHECK_INT_EQ(6, args->argc);
-
-       args_insert(args, 1, src4, false);
-       CHECK_STR_EQ_FREE2("first alpha beta gamma second beta gamma fourth fifth",
-                          args_to_string(args));
-       CHECK_INT_EQ(9, args->argc);
-       args_insert(args, 1, src5, false);
-       CHECK_STR_EQ_FREE2(
-               "first one alpha beta gamma second beta gamma fourth fifth",
-               args_to_string(args));
-       CHECK_INT_EQ(10, args->argc);
-       args_insert(args, 1, src6, false);
-       CHECK_STR_EQ_FREE2(
-               "first one alpha beta gamma second beta gamma fourth fifth",
-               args_to_string(args));
-       CHECK_INT_EQ(10, args->argc);
-
-       args_free(args);
+  struct args* args = args_init_from_string("first second third fourth fifth");
+
+  struct args* src1 = args_init_from_string("alpha beta gamma");
+  struct args* src2 = args_init_from_string("one");
+  struct args* src3 = args_init_from_string("");
+  struct args* src4 = args_init_from_string("alpha beta gamma");
+  struct args* src5 = args_init_from_string("one");
+  struct args* src6 = args_init_from_string("");
+
+  args_insert(args, 2, src1, true);
+  CHECK_STR_EQ_FREE2("first second alpha beta gamma fourth fifth",
+                     args_to_string(args));
+  CHECK_INT_EQ(7, args->argc);
+  args_insert(args, 2, src2, true);
+  CHECK_STR_EQ_FREE2("first second one beta gamma fourth fifth",
+                     args_to_string(args));
+  CHECK_INT_EQ(7, args->argc);
+  args_insert(args, 2, src3, true);
+  CHECK_STR_EQ_FREE2("first second beta gamma fourth fifth",
+                     args_to_string(args));
+  CHECK_INT_EQ(6, args->argc);
+
+  args_insert(args, 1, src4, false);
+  CHECK_STR_EQ_FREE2("first alpha beta gamma second beta gamma fourth fifth",
+                     args_to_string(args));
+  CHECK_INT_EQ(9, args->argc);
+  args_insert(args, 1, src5, false);
+  CHECK_STR_EQ_FREE2(
+    "first one alpha beta gamma second beta gamma fourth fifth",
+    args_to_string(args));
+  CHECK_INT_EQ(10, args->argc);
+  args_insert(args, 1, src6, false);
+  CHECK_STR_EQ_FREE2(
+    "first one alpha beta gamma second beta gamma fourth fifth",
+    args_to_string(args));
+  CHECK_INT_EQ(10, args->argc);
+
+  args_free(args);
 }
 
 TEST_SUITE_END
index c940ec611bc49092a5beb2d7bf91d75ea90f3f8b..6f46cc7c64700c17cb318d18895e37eee9d46c26 100644 (file)
 #include "framework.hpp"
 #include "util.hpp"
 
-extern struct conf *conf;
+extern struct confconf;
 
-static char *
+static char*
 get_root(void)
 {
 #ifndef _WIN32
-       return x_strdup("/");
+  return x_strdup("/");
 #else
-       char volume[4]; // "C:\"
-       GetVolumePathName(get_cwd(), volume, sizeof(volume));
-       return x_strdup(volume);
+  char volume[4]; // "C:\"
+  GetVolumePathName(get_cwd(), volume, sizeof(volume));
+  return x_strdup(volume);
 #endif
 }
 
-static char *
-get_posix_path(char *path)
+static char*
+get_posix_path(charpath)
 {
 #ifndef _WIN32
-       return x_strdup(path);
+  return x_strdup(path);
 #else
-       char *posix;
-       char *p;
-
-       // /-escape volume.
-       if (path[0] >= 'A' && path[0] <= 'Z' && path[1] == ':') {
-               posix = format("/%s", path);
-       } else {
-               posix = x_strdup(path);
-       }
-       // Convert slashes.
-       for (p = posix; *p; p++) {
-               if (*p == '\\') {
-                       *p = '/';
-               }
-       }
-       return posix;
+  char* posix;
+  char* p;
+
+  // /-escape volume.
+  if (path[0] >= 'A' && path[0] <= 'Z' && path[1] == ':') {
+    posix = format("/%s", path);
+  } else {
+    posix = x_strdup(path);
+  }
+  // Convert slashes.
+  for (p = posix; *p; p++) {
+    if (*p == '\\') {
+      *p = '/';
+    }
+  }
+  return posix;
 #endif
 }
 
@@ -66,452 +66,449 @@ TEST_SUITE(argument_processing)
 
 TEST(dash_E_should_result_in_called_for_preprocessing)
 {
-       struct args *orig = args_init_from_string("cc -c foo.c -E");
-       struct args *preprocessed, *compiler;
+  struct args* orig = args_init_from_string("cc -c foo.c -E");
+  struct args *preprocessed, *compiler;
 
-       create_file("foo.c", "");
-       CHECK(!cc_process_args(orig, &preprocessed, &compiler));
-       CHECK_INT_EQ(1, stats_get_pending(STATS_PREPROCESSING));
+  create_file("foo.c", "");
+  CHECK(!cc_process_args(orig, &preprocessed, &compiler));
+  CHECK_INT_EQ(1, stats_get_pending(STATS_PREPROCESSING));
 
-       args_free(orig);
+  args_free(orig);
 }
 
 TEST(dash_M_should_be_unsupported)
 {
-       struct args *orig = args_init_from_string("cc -c foo.c -M");
-       struct args *preprocessed, *compiler;
+  struct args* orig = args_init_from_string("cc -c foo.c -M");
+  struct args *preprocessed, *compiler;
 
-       create_file("foo.c", "");
-       CHECK(!cc_process_args(orig, &preprocessed, &compiler));
-       CHECK_INT_EQ(1, stats_get_pending(STATS_UNSUPPORTED_OPTION));
+  create_file("foo.c", "");
+  CHECK(!cc_process_args(orig, &preprocessed, &compiler));
+  CHECK_INT_EQ(1, stats_get_pending(STATS_UNSUPPORTED_OPTION));
 
-       args_free(orig);
+  args_free(orig);
 }
 
 TEST(dependency_flags_should_only_be_sent_to_the_preprocessor)
 {
-#define CMD \
-       "cc -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 -MQ mq1 -MQ mq2" \
-       " -Wp,-MD,wpmd -Wp,-MMD,wpmmd -Wp,-MP -Wp,-MT,wpmt -Wp,-MQ,wpmq -Wp,-MF,wpf"
-       struct args *orig = args_init_from_string(CMD " -c foo.c -o foo.o");
-       struct args *exp_cpp = args_init_from_string(CMD);
+#define CMD                                                                    \
+  "cc -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 -MQ mq1 -MQ mq2"                  \
+  " -Wp,-MD,wpmd -Wp,-MMD,wpmmd -Wp,-MP -Wp,-MT,wpmt -Wp,-MQ,wpmq -Wp,-MF,wpf"
+  struct args* orig = args_init_from_string(CMD " -c foo.c -o foo.o");
+  struct args* exp_cpp = args_init_from_string(CMD);
 #undef CMD
-       struct args *exp_cc = args_init_from_string("cc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
+  struct args* exp_cc = args_init_from_string("cc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
 
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
 
-       args_free(orig);
+  args_free(orig);
 }
 
 TEST(cpp_only_flags_to_preprocessor_if_run_second_cpp_is_false)
 {
-#define CMD \
-       "cc -I. -idirafter . -iframework. -imacros . -imultilib ." \
-       " -include test.h -include-pch test.pch -iprefix . -iquote ." \
-       " -isysroot . -isystem . -iwithprefix . -iwithprefixbefore ." \
-       " -DTEST_MACRO -DTEST_MACRO2=1 -F. -trigraphs -fworking-directory" \
-       " -fno-working-directory -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2" \
-       " -MQ mq1 -MQ mq2 -Wp,-MD,wpmd -Wp,-MMD,wpmmd -Wp,-MP -Wp,-MT,wpmt" \
-       " -Wp,-MQ,wpmq -Wp,-MF,wpf"
-       struct args *orig = args_init_from_string(CMD " -c foo.c -o foo.o");
-       struct args *exp_cpp = args_init_from_string(CMD);
+#define CMD                                                                    \
+  "cc -I. -idirafter . -iframework. -imacros . -imultilib ."                   \
+  " -include test.h -include-pch test.pch -iprefix . -iquote ."                \
+  " -isysroot . -isystem . -iwithprefix . -iwithprefixbefore ."                \
+  " -DTEST_MACRO -DTEST_MACRO2=1 -F. -trigraphs -fworking-directory"           \
+  " -fno-working-directory -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2"             \
+  " -MQ mq1 -MQ mq2 -Wp,-MD,wpmd -Wp,-MMD,wpmmd -Wp,-MP -Wp,-MT,wpmt"          \
+  " -Wp,-MQ,wpmq -Wp,-MF,wpf"
+  struct args* orig = args_init_from_string(CMD " -c foo.c -o foo.o");
+  struct args* exp_cpp = args_init_from_string(CMD);
 #undef CMD
-       struct args *exp_cc = args_init_from_string("cc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
+  struct args* exp_cc = args_init_from_string("cc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
 
-       conf->run_second_cpp = false;
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+  conf->run_second_cpp = false;
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
 
-       args_free(orig);
+  args_free(orig);
 }
 
 TEST(cpp_only_flags_to_preprocessor_and_compiler_if_run_second_cpp_is_true)
 {
-#define CMD \
-       "cc -I. -idirafter . -iframework. -imacros . -imultilib ." \
-       " -include test.h -include-pch test.pch -iprefix . -iquote ." \
-       " -isysroot . -isystem . -iwithprefix . -iwithprefixbefore ." \
-       " -DTEST_MACRO -DTEST_MACRO2=1 -F. -trigraphs -fworking-directory" \
-       " -fno-working-directory"
-#define DEP_OPTS \
-       " -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 " \
-       " -MQ mq1 -MQ mq2 -Wp,-MD,wpmd -Wp,-MMD,wpmmd"
-       struct args *orig = args_init_from_string(CMD DEP_OPTS " -c foo.c -o foo.o");
-       struct args *exp_cpp = args_init_from_string(CMD DEP_OPTS);
-       struct args *exp_cc = args_init_from_string(CMD " -c");
+#define CMD                                                                    \
+  "cc -I. -idirafter . -iframework. -imacros . -imultilib ."                   \
+  " -include test.h -include-pch test.pch -iprefix . -iquote ."                \
+  " -isysroot . -isystem . -iwithprefix . -iwithprefixbefore ."                \
+  " -DTEST_MACRO -DTEST_MACRO2=1 -F. -trigraphs -fworking-directory"           \
+  " -fno-working-directory"
+#define DEP_OPTS                                                               \
+  " -MD -MMD -MP -MF foo.d -MT mt1 -MT mt2 "                                   \
+  " -MQ mq1 -MQ mq2 -Wp,-MD,wpmd -Wp,-MMD,wpmmd"
+  struct args* orig = args_init_from_string(CMD DEP_OPTS " -c foo.c -o foo.o");
+  struct args* exp_cpp = args_init_from_string(CMD DEP_OPTS);
+  struct args* exp_cc = args_init_from_string(CMD " -c");
 #undef CMD
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
 
-       conf->run_second_cpp = true;
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+  conf->run_second_cpp = true;
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
 
-       args_free(orig);
+  args_free(orig);
 }
 
 TEST(dependency_flags_that_take_an_argument_should_not_require_space_delimiter)
 {
-       struct args *orig = args_init_from_string(
-               "cc -c -MMD -MFfoo.d -MT mt -MTmt -MQmq foo.c -o foo.o");
-       struct args *exp_cpp = args_init_from_string(
-               "cc -MMD -MFfoo.d -MT mt -MTmt -MQmq");
-       struct args *exp_cc = args_init_from_string("cc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig = args_init_from_string(
+    "cc -c -MMD -MFfoo.d -MT mt -MTmt -MQmq foo.c -o foo.o");
+  struct args* exp_cpp =
+    args_init_from_string("cc -MMD -MFfoo.d -MT mt -MTmt -MQmq");
+  struct args* exp_cc = args_init_from_string("cc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(sysroot_should_be_rewritten_if_basedir_is_used)
 {
-       extern char *current_working_dir;
-       char *arg_string;
-       struct args *orig;
-       struct args *act_cpp = NULL, *act_cc = NULL;
-
-       create_file("foo.c", "");
-       free(conf->base_dir);
-       conf->base_dir = get_root();
-       current_working_dir = get_cwd();
-       arg_string = format("cc --sysroot=%s/foo/bar -c foo.c", current_working_dir);
-       orig = args_init_from_string(arg_string);
-       free(arg_string);
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_STR_EQ(act_cpp->argv[1], "--sysroot=./foo/bar");
-
-       args_free(orig);
-       args_free(act_cpp);
-       args_free(act_cc);
+  extern char* current_working_dir;
+  char* arg_string;
+  struct args* orig;
+  struct args *act_cpp = NULL, *act_cc = NULL;
+
+  create_file("foo.c", "");
+  free(conf->base_dir);
+  conf->base_dir = get_root();
+  current_working_dir = get_cwd();
+  arg_string = format("cc --sysroot=%s/foo/bar -c foo.c", current_working_dir);
+  orig = args_init_from_string(arg_string);
+  free(arg_string);
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_STR_EQ(act_cpp->argv[1], "--sysroot=./foo/bar");
+
+  args_free(orig);
+  args_free(act_cpp);
+  args_free(act_cc);
 }
 
 TEST(sysroot_with_separate_argument_should_be_rewritten_if_basedir_is_used)
 {
-       extern char *current_working_dir;
-       char *arg_string;
-       struct args *orig;
-       struct args *act_cpp = NULL, *act_cc = NULL;
-
-       create_file("foo.c", "");
-       free(conf->base_dir);
-       conf->base_dir = get_root();
-       current_working_dir = get_cwd();
-       arg_string = format("cc --sysroot %s/foo -c foo.c", current_working_dir);
-       orig = args_init_from_string(arg_string);
-       free(arg_string);
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_STR_EQ(act_cpp->argv[1], "--sysroot");
-       CHECK_STR_EQ(act_cpp->argv[2], "./foo");
-
-       args_free(orig);
-       args_free(act_cpp);
-       args_free(act_cc);
+  extern char* current_working_dir;
+  char* arg_string;
+  struct args* orig;
+  struct args *act_cpp = NULL, *act_cc = NULL;
+
+  create_file("foo.c", "");
+  free(conf->base_dir);
+  conf->base_dir = get_root();
+  current_working_dir = get_cwd();
+  arg_string = format("cc --sysroot %s/foo -c foo.c", current_working_dir);
+  orig = args_init_from_string(arg_string);
+  free(arg_string);
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_STR_EQ(act_cpp->argv[1], "--sysroot");
+  CHECK_STR_EQ(act_cpp->argv[2], "./foo");
+
+  args_free(orig);
+  args_free(act_cpp);
+  args_free(act_cc);
 }
 
 TEST(MF_flag_with_immediate_argument_should_work_as_last_argument)
 {
-       struct args *orig = args_init_from_string(
-               "cc -c foo.c -o foo.o -MMD -MT bar -MFfoo.d");
-       struct args *exp_cpp = args_init_from_string(
-               "cc -MMD -MT bar -MFfoo.d");
-       struct args *exp_cc = args_init_from_string("cc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig =
+    args_init_from_string("cc -c foo.c -o foo.o -MMD -MT bar -MFfoo.d");
+  struct args* exp_cpp = args_init_from_string("cc -MMD -MT bar -MFfoo.d");
+  struct args* exp_cc = args_init_from_string("cc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(MT_flag_with_immediate_argument_should_work_as_last_argument)
 {
-       struct args *orig = args_init_from_string(
-               "cc -c foo.c -o foo.o -MMD -MFfoo.d -MT foo -MTbar");
-       struct args *exp_cpp = args_init_from_string(
-               "cc -MMD -MFfoo.d -MT foo -MTbar");
-       struct args *exp_cc = args_init_from_string("cc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig =
+    args_init_from_string("cc -c foo.c -o foo.o -MMD -MFfoo.d -MT foo -MTbar");
+  struct args* exp_cpp =
+    args_init_from_string("cc -MMD -MFfoo.d -MT foo -MTbar");
+  struct args* exp_cc = args_init_from_string("cc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(MQ_flag_with_immediate_argument_should_work_as_last_argument)
 {
-       struct args *orig = args_init_from_string(
-               "cc -c foo.c -o foo.o -MMD -MFfoo.d -MQ foo -MQbar");
-       struct args *exp_cpp = args_init_from_string(
-               "cc -MMD -MFfoo.d -MQ foo -MQbar");
-       struct args *exp_cc = args_init_from_string("cc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig =
+    args_init_from_string("cc -c foo.c -o foo.o -MMD -MFfoo.d -MQ foo -MQbar");
+  struct args* exp_cpp =
+    args_init_from_string("cc -MMD -MFfoo.d -MQ foo -MQbar");
+  struct args* exp_cc = args_init_from_string("cc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(MQ_flag_without_immediate_argument_should_not_add_MQobj)
 {
-       struct args *orig = args_init_from_string(
-               "gcc -c -MD -MP -MFfoo.d -MQ foo.d foo.c");
-       struct args *exp_cpp = args_init_from_string(
-               "gcc -MD -MP -MFfoo.d -MQ foo.d");
-       struct args *exp_cc = args_init_from_string("gcc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig =
+    args_init_from_string("gcc -c -MD -MP -MFfoo.d -MQ foo.d foo.c");
+  struct args* exp_cpp =
+    args_init_from_string("gcc -MD -MP -MFfoo.d -MQ foo.d");
+  struct args* exp_cc = args_init_from_string("gcc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(MT_flag_without_immediate_argument_should_not_add_MTobj)
 {
-       struct args *orig = args_init_from_string(
-               "gcc -c -MD -MP -MFfoo.d -MT foo.d foo.c");
-       struct args *exp_cpp = args_init_from_string(
-               "gcc -MD -MP -MFfoo.d -MT foo.d");
-       struct args *exp_cc = args_init_from_string("gcc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig =
+    args_init_from_string("gcc -c -MD -MP -MFfoo.d -MT foo.d foo.c");
+  struct args* exp_cpp =
+    args_init_from_string("gcc -MD -MP -MFfoo.d -MT foo.d");
+  struct args* exp_cc = args_init_from_string("gcc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(MQ_flag_with_immediate_argument_should_not_add_MQobj)
 {
-       struct args *orig = args_init_from_string(
-               "gcc -c -MD -MP -MFfoo.d -MQfoo.d foo.c");
-       struct args *exp_cpp = args_init_from_string(
-               "gcc -MD -MP -MFfoo.d -MQfoo.d");
-       struct args *exp_cc = args_init_from_string("gcc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig =
+    args_init_from_string("gcc -c -MD -MP -MFfoo.d -MQfoo.d foo.c");
+  struct args* exp_cpp = args_init_from_string("gcc -MD -MP -MFfoo.d -MQfoo.d");
+  struct args* exp_cc = args_init_from_string("gcc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(MT_flag_with_immediate_argument_should_not_add_MQobj)
 {
-       struct args *orig = args_init_from_string(
-               "gcc -c -MD -MP -MFfoo.d -MTfoo.d foo.c");
-       struct args *exp_cpp = args_init_from_string(
-               "gcc -MD -MP -MFfoo.d -MTfoo.d");
-       struct args *exp_cc = args_init_from_string("gcc -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       create_file("foo.c", "");
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig =
+    args_init_from_string("gcc -c -MD -MP -MFfoo.d -MTfoo.d foo.c");
+  struct args* exp_cpp = args_init_from_string("gcc -MD -MP -MFfoo.d -MTfoo.d");
+  struct args* exp_cc = args_init_from_string("gcc -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  create_file("foo.c", "");
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(fprofile_flag_with_existing_dir_should_be_rewritten_to_real_path)
 {
-       struct args *orig = args_init_from_string(
-               "gcc -c -fprofile-generate=some/dir foo.c");
-       struct args *exp_cpp = args_init_from_string("gcc");
-       struct args *exp_cc = args_init_from_string("gcc");
-       struct args *act_cpp = NULL, *act_cc = NULL;
-       char *s, *path;
-
-       create_file("foo.c", "");
-       mkdir("some", 0777);
-       mkdir("some/dir", 0777);
-       path = x_realpath("some/dir");
-       s = format("-fprofile-generate=%s", path);
-       free(path);
-       args_add(exp_cpp, s);
-       args_add(exp_cc, s);
-       args_add(exp_cc, "-c");
-       free(s);
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig =
+    args_init_from_string("gcc -c -fprofile-generate=some/dir foo.c");
+  struct args* exp_cpp = args_init_from_string("gcc");
+  struct args* exp_cc = args_init_from_string("gcc");
+  struct args *act_cpp = NULL, *act_cc = NULL;
+  char *s, *path;
+
+  create_file("foo.c", "");
+  mkdir("some", 0777);
+  mkdir("some/dir", 0777);
+  path = x_realpath("some/dir");
+  s = format("-fprofile-generate=%s", path);
+  free(path);
+  args_add(exp_cpp, s);
+  args_add(exp_cc, s);
+  args_add(exp_cc, "-c");
+  free(s);
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(fprofile_flag_with_nonexistent_dir_should_not_be_rewritten)
 {
-       struct args *orig = args_init_from_string(
-               "gcc -c -fprofile-generate=some/dir foo.c");
-       struct args *exp_cpp = args_init_from_string(
-               "gcc -fprofile-generate=some/dir");
-       struct args *exp_cc = args_init_from_string(
-               "gcc -fprofile-generate=some/dir -c");
-       struct args *act_cpp = NULL, *act_cc = NULL;
+  struct args* orig =
+    args_init_from_string("gcc -c -fprofile-generate=some/dir foo.c");
+  struct args* exp_cpp =
+    args_init_from_string("gcc -fprofile-generate=some/dir");
+  struct args* exp_cc =
+    args_init_from_string("gcc -fprofile-generate=some/dir -c");
+  struct args *act_cpp = NULL, *act_cc = NULL;
 
-       create_file("foo.c", "");
+  create_file("foo.c", "");
 
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
 
-       args_free(orig);
+  args_free(orig);
 }
 
 TEST(isystem_flag_with_separate_arg_should_be_rewritten_if_basedir_is_used)
 {
-       extern char *current_working_dir;
-       char *arg_string;
-       struct args *orig;
-       struct args *act_cpp = NULL, *act_cc = NULL;
-
-       create_file("foo.c", "");
-       free(conf->base_dir);
-       conf->base_dir = get_root();
-       current_working_dir = get_cwd();
-       arg_string = format("cc -isystem %s/foo -c foo.c", current_working_dir);
-       orig = args_init_from_string(arg_string);
-       free(arg_string);
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_STR_EQ("./foo", act_cpp->argv[2]);
-
-       args_free(orig);
-       args_free(act_cpp);
-       args_free(act_cc);
+  extern char* current_working_dir;
+  char* arg_string;
+  struct args* orig;
+  struct args *act_cpp = NULL, *act_cc = NULL;
+
+  create_file("foo.c", "");
+  free(conf->base_dir);
+  conf->base_dir = get_root();
+  current_working_dir = get_cwd();
+  arg_string = format("cc -isystem %s/foo -c foo.c", current_working_dir);
+  orig = args_init_from_string(arg_string);
+  free(arg_string);
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_STR_EQ("./foo", act_cpp->argv[2]);
+
+  args_free(orig);
+  args_free(act_cpp);
+  args_free(act_cc);
 }
 
 TEST(isystem_flag_with_concat_arg_should_be_rewritten_if_basedir_is_used)
 {
-       extern char *current_working_dir;
-       char *cwd;
-       char *arg_string;
-       struct args *orig;
-       struct args *act_cpp = NULL, *act_cc = NULL;
-
-       create_file("foo.c", "");
-       free(conf->base_dir);
-       conf->base_dir = x_strdup("/"); // posix
-       current_working_dir = get_cwd();
-       // Windows path doesn't work concatenated.
-       cwd = get_posix_path(current_working_dir);
-       arg_string = format("cc -isystem%s/foo -c foo.c", cwd);
-       orig = args_init_from_string(arg_string);
-       free(arg_string);
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_STR_EQ("-isystem./foo", act_cpp->argv[1]);
-
-       free(cwd);
-       args_free(orig);
-       args_free(act_cpp);
-       args_free(act_cc);
+  extern char* current_working_dir;
+  char* cwd;
+  char* arg_string;
+  struct args* orig;
+  struct args *act_cpp = NULL, *act_cc = NULL;
+
+  create_file("foo.c", "");
+  free(conf->base_dir);
+  conf->base_dir = x_strdup("/"); // posix
+  current_working_dir = get_cwd();
+  // Windows path doesn't work concatenated.
+  cwd = get_posix_path(current_working_dir);
+  arg_string = format("cc -isystem%s/foo -c foo.c", cwd);
+  orig = args_init_from_string(arg_string);
+  free(arg_string);
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_STR_EQ("-isystem./foo", act_cpp->argv[1]);
+
+  free(cwd);
+  args_free(orig);
+  args_free(act_cpp);
+  args_free(act_cc);
 }
 
 TEST(I_flag_with_concat_arg_should_be_rewritten_if_basedir_is_used)
 {
-       extern char *current_working_dir;
-       char *cwd;
-       char *arg_string;
-       struct args *orig;
-       struct args *act_cpp = NULL, *act_cc = NULL;
-
-       create_file("foo.c", "");
-       free(conf->base_dir);
-       conf->base_dir = x_strdup("/"); // posix
-       current_working_dir = get_cwd();
-       // Windows path doesn't work concatenated.
-       cwd = get_posix_path(current_working_dir);
-       arg_string = format("cc -I%s/foo -c foo.c", cwd);
-       orig = args_init_from_string(arg_string);
-       free(arg_string);
-
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_STR_EQ("-I./foo", act_cpp->argv[1]);
-
-       free(cwd);
-       args_free(orig);
-       args_free(act_cpp);
-       args_free(act_cc);
+  extern char* current_working_dir;
+  char* cwd;
+  char* arg_string;
+  struct args* orig;
+  struct args *act_cpp = NULL, *act_cc = NULL;
+
+  create_file("foo.c", "");
+  free(conf->base_dir);
+  conf->base_dir = x_strdup("/"); // posix
+  current_working_dir = get_cwd();
+  // Windows path doesn't work concatenated.
+  cwd = get_posix_path(current_working_dir);
+  arg_string = format("cc -I%s/foo -c foo.c", cwd);
+  orig = args_init_from_string(arg_string);
+  free(arg_string);
+
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_STR_EQ("-I./foo", act_cpp->argv[1]);
+
+  free(cwd);
+  args_free(orig);
+  args_free(act_cpp);
+  args_free(act_cc);
 }
 
 TEST(debug_flag_order_with_known_option_first)
 {
-       struct args *orig = args_init_from_string("cc -g1 -gsplit-dwarf foo.c -c");
-       struct args *exp_cpp = args_init_from_string("cc -g1 -gsplit-dwarf");
-       struct args *exp_cc = args_init_from_string("cc -g1 -gsplit-dwarf -c");
-       struct args *act_cpp = NULL;
-       struct args *act_cc = NULL;
-
-       create_file("foo.c", "");
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig = args_init_from_string("cc -g1 -gsplit-dwarf foo.c -c");
+  struct args* exp_cpp = args_init_from_string("cc -g1 -gsplit-dwarf");
+  struct args* exp_cc = args_init_from_string("cc -g1 -gsplit-dwarf -c");
+  struct args* act_cpp = NULL;
+  struct args* act_cc = NULL;
+
+  create_file("foo.c", "");
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(debug_flag_order_with_known_option_last)
 {
-       struct args *orig = args_init_from_string("cc -gsplit-dwarf -g1 foo.c -c");
-       struct args *exp_cpp = args_init_from_string("cc -gsplit-dwarf -g1");
-       struct args *exp_cc = args_init_from_string("cc -gsplit-dwarf -g1 -c");
-       struct args *act_cpp = NULL;
-       struct args *act_cc = NULL;
-
-       create_file("foo.c", "");
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig = args_init_from_string("cc -gsplit-dwarf -g1 foo.c -c");
+  struct args* exp_cpp = args_init_from_string("cc -gsplit-dwarf -g1");
+  struct args* exp_cc = args_init_from_string("cc -gsplit-dwarf -g1 -c");
+  struct args* act_cpp = NULL;
+  struct args* act_cc = NULL;
+
+  create_file("foo.c", "");
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST(options_not_to_be_passed_to_the_preprocesor)
 {
-       struct args *orig = args_init_from_string(
-               "cc -Wa,foo foo.c -g -Xlinker fie -Xlinker,fum -c -Werror");
-       struct args *exp_cpp = args_init_from_string("cc -g");
-       struct args *exp_cc = args_init_from_string(
-               "cc -g -Wa,foo -Xlinker fie -Xlinker,fum -Werror -c");
-       struct args *act_cpp = NULL;
-       struct args *act_cc = NULL;
-
-       create_file("foo.c", "");
-       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
-       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
-       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
-
-       args_free(orig);
+  struct args* orig = args_init_from_string(
+    "cc -Wa,foo foo.c -g -Xlinker fie -Xlinker,fum -c -Werror");
+  struct args* exp_cpp = args_init_from_string("cc -g");
+  struct args* exp_cc =
+    args_init_from_string("cc -g -Wa,foo -Xlinker fie -Xlinker,fum -Werror -c");
+  struct args* act_cpp = NULL;
+  struct args* act_cc = NULL;
+
+  create_file("foo.c", "");
+  CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+  CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+  CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+  args_free(orig);
 }
 
 TEST_SUITE_END
index 1b0c5bf51d31bb04e514d03a9d0e06828650c351..99c3b2bd9a3d9428862e666e17b12191766afdfb 100644 (file)
@@ -26,115 +26,115 @@ TEST_SUITE(compopt)
 
 TEST(option_table_should_be_sorted)
 {
-       bool compopt_verify_sortedness(void);
-       CHECK(compopt_verify_sortedness());
+  bool compopt_verify_sortedness(void);
+  CHECK(compopt_verify_sortedness());
 }
 
 TEST(dash_I_affects_cpp)
 {
-       CHECK(compopt_affects_cpp("-I"));
-       CHECK(!compopt_affects_cpp("-Ifoo"));
+  CHECK(compopt_affects_cpp("-I"));
+  CHECK(!compopt_affects_cpp("-Ifoo"));
 }
 
 TEST(compopt_short)
 {
-       CHECK(compopt_short(compopt_affects_cpp, "-Ifoo"));
-       CHECK(!compopt_short(compopt_affects_cpp, "-include"));
+  CHECK(compopt_short(compopt_affects_cpp, "-Ifoo"));
+  CHECK(!compopt_short(compopt_affects_cpp, "-include"));
 }
 
 TEST(dash_V_doesnt_affect_cpp)
 {
-       CHECK(!compopt_affects_cpp("-V"));
+  CHECK(!compopt_affects_cpp("-V"));
 }
 
 TEST(dash_doesntexist_doesnt_affect_cpp)
 {
-       CHECK(!compopt_affects_cpp("-doesntexist"));
+  CHECK(!compopt_affects_cpp("-doesntexist"));
 }
 
 TEST(dash_MM_too_hard)
 {
-       CHECK(compopt_too_hard("-MM"));
+  CHECK(compopt_too_hard("-MM"));
 }
 
 TEST(dash_save_temps_too_hard)
 {
-       CHECK(compopt_too_hard("-save-temps"));
+  CHECK(compopt_too_hard("-save-temps"));
 }
 
 TEST(dash_save_temps_cwd_too_hard)
 {
-       CHECK(compopt_too_hard("-save-temps=cwd"));
+  CHECK(compopt_too_hard("-save-temps=cwd"));
 }
 
 TEST(dash_save_temps_obj_too_hard)
 {
-       CHECK(compopt_too_hard("-save-temps=obj"));
+  CHECK(compopt_too_hard("-save-temps=obj"));
 }
 
 TEST(dash_MD_not_too_hard)
 {
-       CHECK(!compopt_too_hard("-MD"));
+  CHECK(!compopt_too_hard("-MD"));
 }
 
 TEST(dash_fprofile_arcs_not_too_hard)
 {
-       CHECK(!compopt_too_hard("-fprofile-arcs"));
+  CHECK(!compopt_too_hard("-fprofile-arcs"));
 }
 
 TEST(dash_ftest_coverage_not_too_hard)
 {
-       CHECK(!compopt_too_hard("-ftest-coverage"));
+  CHECK(!compopt_too_hard("-ftest-coverage"));
 }
 
 TEST(dash_fstack_usage_not_too_hard)
 {
-       CHECK(!compopt_too_hard("-fstack-usage"));
+  CHECK(!compopt_too_hard("-fstack-usage"));
 }
 
 TEST(dash_doesntexist_not_too_hard)
 {
-       CHECK(!compopt_too_hard("-doesntexist"));
+  CHECK(!compopt_too_hard("-doesntexist"));
 }
 
 TEST(dash_Xpreprocessor_too_hard_for_direct_mode)
 {
-       CHECK(compopt_too_hard_for_direct_mode("-Xpreprocessor"));
+  CHECK(compopt_too_hard_for_direct_mode("-Xpreprocessor"));
 }
 
 TEST(dash_nostdinc_not_too_hard_for_direct_mode)
 {
-       CHECK(!compopt_too_hard_for_direct_mode("-nostdinc"));
+  CHECK(!compopt_too_hard_for_direct_mode("-nostdinc"));
 }
 
 TEST(dash_I_takes_path)
 {
-       CHECK(compopt_takes_path("-I"));
+  CHECK(compopt_takes_path("-I"));
 }
 
 TEST(dash_Xlinker_takes_arg)
 {
-       CHECK(compopt_takes_arg("-Xlinker"));
+  CHECK(compopt_takes_arg("-Xlinker"));
 }
 
 TEST(dash_xxx_doesnt_take_arg)
 {
-       CHECK(!compopt_takes_arg("-xxx"));
+  CHECK(!compopt_takes_arg("-xxx"));
 }
 
 TEST(dash_iframework_prefix_affects_cpp)
 {
-       CHECK(compopt_prefix_affects_cpp("-iframework"));
+  CHECK(compopt_prefix_affects_cpp("-iframework"));
 }
 
 TEST(dash_analyze_too_hard)
 {
-       CHECK(compopt_too_hard("-analyze"));
+  CHECK(compopt_too_hard("-analyze"));
 }
 
 TEST(dash_dash_analyze_too_hard)
 {
-       CHECK(compopt_too_hard("--analyze"));
+  CHECK(compopt_too_hard("--analyze"));
 }
 
 TEST_SUITE_END
index 76411e7b9b217c4515005047337bbb0212064cc7..f19704c0c655213ce3681eb5abb52d6ee9cf7746 100644 (file)
@@ -24,45 +24,45 @@ TEST_SUITE(compr_type_none)
 
 TEST(small_roundtrip)
 {
-       const uint64_t expected_foobar_checksum = 0xa2aa05ed9085aaf9ULL;
+  const uint64_t expected_foobar_checksum = 0xa2aa05ed9085aaf9ULL;
 
-       XXH64_state_t *checksum = XXH64_createState();
-       XXH64_reset(checksum, 0);
+  XXH64_state_t* checksum = XXH64_createState();
+  XXH64_reset(checksum, 0);
 
-       FILE *f = fopen("data.uncompressed", "w");
-       struct compressor *compr_none = compressor_from_type(COMPR_TYPE_NONE);
-       struct compr_state *c_state = compr_none->init(f, -1, checksum);
-       CHECK(c_state);
+  FILE* f = fopen("data.uncompressed", "w");
+  struct compressor* compr_none = compressor_from_type(COMPR_TYPE_NONE);
+  struct compr_state* c_state = compr_none->init(f, -1, checksum);
+  CHECK(c_state);
 
-       CHECK(compr_none->write(c_state, "foobar", 6));
+  CHECK(compr_none->write(c_state, "foobar", 6));
 
-       CHECK(compr_none->free(c_state));
-       fclose(f);
+  CHECK(compr_none->free(c_state));
+  fclose(f);
 
-       CHECK_INT_EQ(XXH64_digest(checksum), expected_foobar_checksum);
+  CHECK_INT_EQ(XXH64_digest(checksum), expected_foobar_checksum);
 
-       XXH64_reset(checksum, 0);
-       f = fopen("data.uncompressed", "r");
-       struct decompressor *decompr_none = decompressor_from_type(COMPR_TYPE_NONE);
-       struct decompr_state *d_state = decompr_none->init(f, checksum);
-       CHECK(d_state);
+  XXH64_reset(checksum, 0);
+  f = fopen("data.uncompressed", "r");
+  struct decompressor* decompr_none = decompressor_from_type(COMPR_TYPE_NONE);
+  struct decompr_state* d_state = decompr_none->init(f, checksum);
+  CHECK(d_state);
 
-       char buffer[4];
-       CHECK(decompr_none->read(d_state, buffer, 4));
-       CHECK(memcmp(buffer, "foob", 4) == 0);
-       CHECK(decompr_none->read(d_state, buffer, 2));
-       CHECK(memcmp(buffer, "ar", 2) == 0);
+  char buffer[4];
+  CHECK(decompr_none->read(d_state, buffer, 4));
+  CHECK(memcmp(buffer, "foob", 4) == 0);
+  CHECK(decompr_none->read(d_state, buffer, 2));
+  CHECK(memcmp(buffer, "ar", 2) == 0);
 
-       // Nothing left to read.
-       CHECK(!decompr_none->read(d_state, buffer, 1));
+  // Nothing left to read.
+  CHECK(!decompr_none->read(d_state, buffer, 1));
 
-       // Error state is remembered.
-       CHECK(!decompr_none->free(d_state));
-       fclose(f);
+  // Error state is remembered.
+  CHECK(!decompr_none->free(d_state));
+  fclose(f);
 
-       CHECK_INT_EQ(XXH64_digest(checksum), expected_foobar_checksum);
+  CHECK_INT_EQ(XXH64_digest(checksum), expected_foobar_checksum);
 
-       XXH64_freeState(checksum);
+  XXH64_freeState(checksum);
 }
 
 TEST_SUITE_END
index 89d75b7fbeb718766815b6dedf7f5125c9bbd37a..393bb87649e44f2e03642d54020f30795fbce1f3 100644 (file)
@@ -24,110 +24,110 @@ TEST_SUITE(compr_type_zstd)
 
 TEST(small_roundtrip)
 {
-       const uint64_t expected_foobar_checksum = 0xa2aa05ed9085aaf9ULL;
+  const uint64_t expected_foobar_checksum = 0xa2aa05ed9085aaf9ULL;
 
-       XXH64_state_t *checksum = XXH64_createState();
-       XXH64_reset(checksum, 0);
+  XXH64_state_t* checksum = XXH64_createState();
+  XXH64_reset(checksum, 0);
 
-       FILE *f = fopen("data.zstd", "w");
-       struct compressor *compr_zstd = compressor_from_type(COMPR_TYPE_ZSTD);
-       struct compr_state *c_state = compr_zstd->init(f, -1, checksum);
-       CHECK(c_state);
+  FILE* f = fopen("data.zstd", "w");
+  struct compressor* compr_zstd = compressor_from_type(COMPR_TYPE_ZSTD);
+  struct compr_state* c_state = compr_zstd->init(f, -1, checksum);
+  CHECK(c_state);
 
-       CHECK(compr_zstd->write(c_state, "foobar", 6));
+  CHECK(compr_zstd->write(c_state, "foobar", 6));
 
-       CHECK(compr_zstd->free(c_state));
-       fclose(f);
+  CHECK(compr_zstd->free(c_state));
+  fclose(f);
 
-       CHECK_INT_EQ(XXH64_digest(checksum), expected_foobar_checksum);
+  CHECK_INT_EQ(XXH64_digest(checksum), expected_foobar_checksum);
 
-       XXH64_reset(checksum, 0);
-       f = fopen("data.zstd", "r");
-       struct decompressor *decompr_zstd = decompressor_from_type(COMPR_TYPE_ZSTD);
-       struct decompr_state *d_state = decompr_zstd->init(f, checksum);
-       CHECK(d_state);
+  XXH64_reset(checksum, 0);
+  f = fopen("data.zstd", "r");
+  struct decompressor* decompr_zstd = decompressor_from_type(COMPR_TYPE_ZSTD);
+  struct decompr_state* d_state = decompr_zstd->init(f, checksum);
+  CHECK(d_state);
 
-       char buffer[4];
-       CHECK(decompr_zstd->read(d_state, buffer, 4));
-       CHECK(memcmp(buffer, "foob", 4) == 0);
-       CHECK(decompr_zstd->read(d_state, buffer, 2));
-       CHECK(memcmp(buffer, "ar", 2) == 0);
+  char buffer[4];
+  CHECK(decompr_zstd->read(d_state, buffer, 4));
+  CHECK(memcmp(buffer, "foob", 4) == 0);
+  CHECK(decompr_zstd->read(d_state, buffer, 2));
+  CHECK(memcmp(buffer, "ar", 2) == 0);
 
-       // Nothing left to read.
-       CHECK(!decompr_zstd->read(d_state, buffer, 1));
+  // Nothing left to read.
+  CHECK(!decompr_zstd->read(d_state, buffer, 1));
 
-       // Error state is remembered.
-       CHECK(!decompr_zstd->free(d_state));
-       fclose(f);
+  // Error state is remembered.
+  CHECK(!decompr_zstd->free(d_state));
+  fclose(f);
 
-       CHECK_INT_EQ(XXH64_digest(checksum), expected_foobar_checksum);
+  CHECK_INT_EQ(XXH64_digest(checksum), expected_foobar_checksum);
 
-       XXH64_freeState(checksum);
+  XXH64_freeState(checksum);
 }
 
 TEST(large_compressible_roundtrip)
 {
-       char data[] = "The quick brown fox jumps over the lazy dog";
+  char data[] = "The quick brown fox jumps over the lazy dog";
 
-       FILE *f = fopen("data.zstd", "w");
-       struct compressor *compr_zstd = compressor_from_type(COMPR_TYPE_ZSTD);
-       struct compr_state *c_state = compr_zstd->init(f, 1, NULL);
-       CHECK(c_state);
+  FILE* f = fopen("data.zstd", "w");
+  struct compressor* compr_zstd = compressor_from_type(COMPR_TYPE_ZSTD);
+  struct compr_state* c_state = compr_zstd->init(f, 1, NULL);
+  CHECK(c_state);
 
-       for (size_t i = 0; i < 1000; i++) {
-               CHECK(compr_zstd->write(c_state, data, sizeof(data)));
-       }
+  for (size_t i = 0; i < 1000; i++) {
+    CHECK(compr_zstd->write(c_state, data, sizeof(data)));
+  }
 
-       CHECK(compr_zstd->free(c_state));
-       fclose(f);
+  CHECK(compr_zstd->free(c_state));
+  fclose(f);
 
-       f = fopen("data.zstd", "r");
-       struct decompressor *decompr_zstd = decompressor_from_type(COMPR_TYPE_ZSTD);
-       struct decompr_state *d_state = decompr_zstd->init(f, NULL);
-       CHECK(d_state);
+  f = fopen("data.zstd", "r");
+  struct decompressor* decompr_zstd = decompressor_from_type(COMPR_TYPE_ZSTD);
+  struct decompr_state* d_state = decompr_zstd->init(f, NULL);
+  CHECK(d_state);
 
-       char buffer[sizeof(data)];
-       for (size_t i = 0; i < 1000; i++) {
-               CHECK(decompr_zstd->read(d_state, buffer, sizeof(buffer)));
-               CHECK(memcmp(buffer, data, sizeof(data)) == 0);
-       }
+  char buffer[sizeof(data)];
+  for (size_t i = 0; i < 1000; i++) {
+    CHECK(decompr_zstd->read(d_state, buffer, sizeof(buffer)));
+    CHECK(memcmp(buffer, data, sizeof(data)) == 0);
+  }
 
-       // Nothing left to read.
-       CHECK(!decompr_zstd->read(d_state, buffer, 1));
+  // Nothing left to read.
+  CHECK(!decompr_zstd->read(d_state, buffer, 1));
 
-       // Error state is remembered.
-       CHECK(!decompr_zstd->free(d_state));
-       fclose(f);
+  // Error state is remembered.
+  CHECK(!decompr_zstd->free(d_state));
+  fclose(f);
 }
 
 TEST(large_uncompressible_roundtrip)
 {
-       char data[100000];
-       for (size_t i = 0; i < sizeof(data); i++) {
-               data[i] = rand() % 256;
-       }
+  char data[100000];
+  for (size_t i = 0; i < sizeof(data); i++) {
+    data[i] = rand() % 256;
+  }
 
-       FILE *f = fopen("data.zstd", "w");
-       struct compressor *compr_zstd = compressor_from_type(COMPR_TYPE_ZSTD);
-       struct compr_state *c_state = compr_zstd->init(f, 1, NULL);
-       CHECK(c_state);
+  FILE* f = fopen("data.zstd", "w");
+  struct compressor* compr_zstd = compressor_from_type(COMPR_TYPE_ZSTD);
+  struct compr_state* c_state = compr_zstd->init(f, 1, NULL);
+  CHECK(c_state);
 
-       CHECK(compr_zstd->write(c_state, data, sizeof(data)));
+  CHECK(compr_zstd->write(c_state, data, sizeof(data)));
 
-       CHECK(compr_zstd->free(c_state));
-       fclose(f);
+  CHECK(compr_zstd->free(c_state));
+  fclose(f);
 
-       f = fopen("data.zstd", "r");
-       struct decompressor *decompr_zstd = decompressor_from_type(COMPR_TYPE_ZSTD);
-       struct decompr_state *d_state = decompr_zstd->init(f, NULL);
-       CHECK(d_state);
+  f = fopen("data.zstd", "r");
+  struct decompressor* decompr_zstd = decompressor_from_type(COMPR_TYPE_ZSTD);
+  struct decompr_state* d_state = decompr_zstd->init(f, NULL);
+  CHECK(d_state);
 
-       char buffer[sizeof(data)];
-       CHECK(decompr_zstd->read(d_state, buffer, sizeof(buffer)));
-       CHECK(memcmp(buffer, data, sizeof(data)) == 0);
+  char buffer[sizeof(data)];
+  CHECK(decompr_zstd->read(d_state, buffer, sizeof(buffer)));
+  CHECK(memcmp(buffer, data, sizeof(data)) == 0);
 
-       CHECK(decompr_zstd->free(d_state));
-       fclose(f);
+  CHECK(decompr_zstd->free(d_state));
+  fclose(f);
 }
 
 TEST_SUITE_END
index b2a765ae1f44eac6008e2473627dc5eb5332ab8d..d4c10bcf195f35e14722e849d221f21181d05be6 100644 (file)
 #include "util.hpp"
 
 #define N_CONFIG_ITEMS 35
-static struct {
-       char *descr;
-       char *origin;
+static struct
+{
+  char* descr;
+  char* origin;
 } received_conf_items[N_CONFIG_ITEMS];
 static size_t n_received_conf_items = 0;
 
@@ -32,541 +33,530 @@ static char COMPRESS_1_ENV[] = "CCACHE_COMPRESS=1";
 static char NOCOMPRESS_1_ENV[] = "CCACHE_NOCOMPRESS=1";
 
 static void
-conf_item_receiver(const char *descr, const char *origin, void *context)
+conf_item_receiver(const char* descr, const char* origin, void* context)
 {
-       (void)context;
-       received_conf_items[n_received_conf_items].descr = x_strdup(descr);
-       received_conf_items[n_received_conf_items].origin = x_strdup(origin);
-       ++n_received_conf_items;
+  (void)context;
+  received_conf_items[n_received_conf_items].descr = x_strdup(descr);
+  received_conf_items[n_received_conf_items].origin = x_strdup(origin);
+  ++n_received_conf_items;
 }
 
 static void
 free_received_conf_items(void)
 {
-       while (n_received_conf_items > 0) {
-               --n_received_conf_items;
-               free(received_conf_items[n_received_conf_items].descr);
-               free(received_conf_items[n_received_conf_items].origin);
-       }
+  while (n_received_conf_items > 0) {
+    --n_received_conf_items;
+    free(received_conf_items[n_received_conf_items].descr);
+    free(received_conf_items[n_received_conf_items].origin);
+  }
 }
 
 TEST_SUITE(conf)
 
 TEST(conf_create)
 {
-       struct conf *conf = conf_create();
-       CHECK_STR_EQ("", conf->base_dir);
-       CHECK_STR_EQ_FREE1(format("%s/.ccache", get_home_directory()),
-                          conf->cache_dir);
-       CHECK_INT_EQ(2, conf->cache_dir_levels);
-       CHECK_STR_EQ("", conf->compiler);
-       CHECK_STR_EQ("mtime", conf->compiler_check);
-       CHECK(conf->compression);
-       CHECK_INT_EQ(0, conf->compression_level);
-       CHECK_STR_EQ("", conf->cpp_extension);
-       CHECK(!conf->debug);
-       CHECK(!conf->depend_mode);
-       CHECK(conf->direct_mode);
-       CHECK(!conf->disable);
-       CHECK_STR_EQ("", conf->extra_files_to_hash);
-       CHECK(!conf->file_clone);
-       CHECK(!conf->hard_link);
-       CHECK(conf->hash_dir);
-       CHECK_STR_EQ("", conf->ignore_headers_in_manifest);
-       CHECK(!conf->keep_comments_cpp);
-       CHECK_DOUBLE_EQ(0.8, conf->limit_multiple);
-       CHECK_STR_EQ("", conf->log_file);
-       CHECK_INT_EQ(0, conf->max_files);
-       CHECK_INT_EQ((uint64_t)5 * 1000 * 1000 * 1000, conf->max_size);
-       CHECK_STR_EQ("", conf->path);
-       CHECK(!conf->pch_external_checksum);
-       CHECK_STR_EQ("", conf->prefix_command);
-       CHECK_STR_EQ("", conf->prefix_command_cpp);
-       CHECK(!conf->read_only);
-       CHECK(!conf->read_only_direct);
-       CHECK(!conf->recache);
-       CHECK(conf->run_second_cpp);
-       CHECK_INT_EQ(0, conf->sloppiness);
-       CHECK(conf->stats);
-       CHECK_STR_EQ("", conf->temporary_dir);
-       CHECK_INT_EQ(UINT_MAX, conf->umask);
-       CHECK(!conf->unify);
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  CHECK_STR_EQ("", conf->base_dir);
+  CHECK_STR_EQ_FREE1(format("%s/.ccache", get_home_directory()),
+                     conf->cache_dir);
+  CHECK_INT_EQ(2, conf->cache_dir_levels);
+  CHECK_STR_EQ("", conf->compiler);
+  CHECK_STR_EQ("mtime", conf->compiler_check);
+  CHECK(conf->compression);
+  CHECK_INT_EQ(0, conf->compression_level);
+  CHECK_STR_EQ("", conf->cpp_extension);
+  CHECK(!conf->debug);
+  CHECK(!conf->depend_mode);
+  CHECK(conf->direct_mode);
+  CHECK(!conf->disable);
+  CHECK_STR_EQ("", conf->extra_files_to_hash);
+  CHECK(!conf->file_clone);
+  CHECK(!conf->hard_link);
+  CHECK(conf->hash_dir);
+  CHECK_STR_EQ("", conf->ignore_headers_in_manifest);
+  CHECK(!conf->keep_comments_cpp);
+  CHECK_DOUBLE_EQ(0.8, conf->limit_multiple);
+  CHECK_STR_EQ("", conf->log_file);
+  CHECK_INT_EQ(0, conf->max_files);
+  CHECK_INT_EQ((uint64_t)5 * 1000 * 1000 * 1000, conf->max_size);
+  CHECK_STR_EQ("", conf->path);
+  CHECK(!conf->pch_external_checksum);
+  CHECK_STR_EQ("", conf->prefix_command);
+  CHECK_STR_EQ("", conf->prefix_command_cpp);
+  CHECK(!conf->read_only);
+  CHECK(!conf->read_only_direct);
+  CHECK(!conf->recache);
+  CHECK(conf->run_second_cpp);
+  CHECK_INT_EQ(0, conf->sloppiness);
+  CHECK(conf->stats);
+  CHECK_STR_EQ("", conf->temporary_dir);
+  CHECK_INT_EQ(UINT_MAX, conf->umask);
+  CHECK(!conf->unify);
+  conf_free(conf);
 }
 
 TEST(conf_read_valid_config)
 {
-       struct conf *conf = conf_create();
-       char *errmsg, *user;
-       putenv(USER_ENV);
-       user = getenv("USER");
-       CHECK_STR_EQ("rabbit", user);
-       create_file(
-               "ccache.conf",
+  struct conf* conf = conf_create();
+  char *errmsg, *user;
+  putenv(USER_ENV);
+  user = getenv("USER");
+  CHECK_STR_EQ("rabbit", user);
+  create_file(
+    "ccache.conf",
 #ifndef _WIN32
-               "base_dir =  /$USER/foo/${USER} \n"
+    "base_dir =  /$USER/foo/${USER} \n"
 #else
-               "base_dir = C:/$USER/foo/${USER}\n"
+    "base_dir = C:/$USER/foo/${USER}\n"
 #endif
-               "cache_dir=\n"
-               "cache_dir = $USER$/${USER}/.ccache\n"
-               "\n"
-               "\n"
-               "  #A comment\n"
-               " cache_dir_levels = 4\n"
-               "\t compiler = foo\n"
-               "compiler_check = none\n"
-               "compression=false\n"
-               "compression_level= 2\n"
-               "cpp_extension = .foo\n"
-               "depend_mode = true\n"
-               "direct_mode = false\n"
-               "disable = true\n"
-               "extra_files_to_hash = a:b c:$USER\n"
-               "file_clone = true\n"
-               "hard_link = true\n"
-               "hash_dir = false\n"
-               "ignore_headers_in_manifest = a:b/c\n"
-               "keep_comments_cpp = true\n"
-               "limit_multiple = 1.0\n"
-               "log_file = $USER${USER} \n"
-               "max_files = 17\n"
-               "max_size = 123M\n"
-               "path = $USER.x\n"
-               "pch_external_checksum = true\n"
-               "prefix_command = x$USER\n"
-               "prefix_command_cpp = y\n"
-               "read_only = true\n"
-               "read_only_direct = true\n"
-               "recache = true\n"
-               "run_second_cpp = false\n"
-               "sloppiness =     file_macro   ,time_macros,  include_file_mtime,include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_defines ,  no_system_headers,system_headers,clang_index_store\n"
-               "stats = false\n"
-               "temporary_dir = ${USER}_foo\n"
-               "umask = 777\n"
-               "unify = true"); // Note: no newline.
-       CHECK(conf_read(conf, "ccache.conf", &errmsg));
-       CHECK(!errmsg);
+    "cache_dir=\n"
+    "cache_dir = $USER$/${USER}/.ccache\n"
+    "\n"
+    "\n"
+    "  #A comment\n"
+    " cache_dir_levels = 4\n"
+    "\t compiler = foo\n"
+    "compiler_check = none\n"
+    "compression=false\n"
+    "compression_level= 2\n"
+    "cpp_extension = .foo\n"
+    "depend_mode = true\n"
+    "direct_mode = false\n"
+    "disable = true\n"
+    "extra_files_to_hash = a:b c:$USER\n"
+    "file_clone = true\n"
+    "hard_link = true\n"
+    "hash_dir = false\n"
+    "ignore_headers_in_manifest = a:b/c\n"
+    "keep_comments_cpp = true\n"
+    "limit_multiple = 1.0\n"
+    "log_file = $USER${USER} \n"
+    "max_files = 17\n"
+    "max_size = 123M\n"
+    "path = $USER.x\n"
+    "pch_external_checksum = true\n"
+    "prefix_command = x$USER\n"
+    "prefix_command_cpp = y\n"
+    "read_only = true\n"
+    "read_only_direct = true\n"
+    "recache = true\n"
+    "run_second_cpp = false\n"
+    "sloppiness =     file_macro   ,time_macros,  "
+    "include_file_mtime,include_file_ctime,file_stat_matches,file_stat_"
+    "matches_ctime,pch_defines ,  "
+    "no_system_headers,system_headers,clang_index_store\n"
+    "stats = false\n"
+    "temporary_dir = ${USER}_foo\n"
+    "umask = 777\n"
+    "unify = true"); // Note: no newline.
+  CHECK(conf_read(conf, "ccache.conf", &errmsg));
+  CHECK(!errmsg);
 
 #ifndef _WIN32
-       CHECK_STR_EQ_FREE1(format("/%s/foo/%s", user, user), conf->base_dir);
+  CHECK_STR_EQ_FREE1(format("/%s/foo/%s", user, user), conf->base_dir);
 #else
-       CHECK_STR_EQ_FREE1(format("C:/%s/foo/%s", user, user), conf->base_dir);
+  CHECK_STR_EQ_FREE1(format("C:/%s/foo/%s", user, user), conf->base_dir);
 #endif
-       CHECK_STR_EQ_FREE1(format("%s$/%s/.ccache", user, user), conf->cache_dir);
-       CHECK_INT_EQ(4, conf->cache_dir_levels);
-       CHECK_STR_EQ("foo", conf->compiler);
-       CHECK_STR_EQ("none", conf->compiler_check);
-       CHECK(!conf->compression);
-       CHECK_INT_EQ(2, conf->compression_level);
-       CHECK_STR_EQ(".foo", conf->cpp_extension);
-       CHECK(conf->depend_mode);
-       CHECK(!conf->direct_mode);
-       CHECK(conf->disable);
-       CHECK_STR_EQ_FREE1(format("a:b c:%s", user), conf->extra_files_to_hash);
-       CHECK(conf->file_clone);
-       CHECK(conf->hard_link);
-       CHECK(!conf->hash_dir);
-       CHECK_STR_EQ("a:b/c", conf->ignore_headers_in_manifest);
-       CHECK(conf->keep_comments_cpp);
-       CHECK_DOUBLE_EQ(1.0, conf->limit_multiple);
-       CHECK_STR_EQ_FREE1(format("%s%s", user, user), conf->log_file);
-       CHECK_INT_EQ(17, conf->max_files);
-       CHECK_INT_EQ(123 * 1000 * 1000, conf->max_size);
-       CHECK_STR_EQ_FREE1(format("%s.x", user), conf->path);
-       CHECK(conf->pch_external_checksum);
-       CHECK_STR_EQ_FREE1(format("x%s", user), conf->prefix_command);
-       CHECK_STR_EQ("y", conf->prefix_command_cpp);
-       CHECK(conf->read_only);
-       CHECK(conf->read_only_direct);
-       CHECK(conf->recache);
-       CHECK(!conf->run_second_cpp);
-       CHECK_INT_EQ(
-               SLOPPY_INCLUDE_FILE_MTIME
-               |SLOPPY_INCLUDE_FILE_CTIME
-               |SLOPPY_FILE_MACRO
-               |SLOPPY_TIME_MACROS
-               |SLOPPY_FILE_STAT_MATCHES
-               |SLOPPY_FILE_STAT_MATCHES_CTIME
-               |SLOPPY_SYSTEM_HEADERS
-               |SLOPPY_PCH_DEFINES
-               |SLOPPY_CLANG_INDEX_STORE,
-               conf->sloppiness);
-       CHECK(!conf->stats);
-       CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
-       CHECK_INT_EQ(0777, conf->umask);
-       CHECK(conf->unify);
-
-       conf_free(conf);
+  CHECK_STR_EQ_FREE1(format("%s$/%s/.ccache", user, user), conf->cache_dir);
+  CHECK_INT_EQ(4, conf->cache_dir_levels);
+  CHECK_STR_EQ("foo", conf->compiler);
+  CHECK_STR_EQ("none", conf->compiler_check);
+  CHECK(!conf->compression);
+  CHECK_INT_EQ(2, conf->compression_level);
+  CHECK_STR_EQ(".foo", conf->cpp_extension);
+  CHECK(conf->depend_mode);
+  CHECK(!conf->direct_mode);
+  CHECK(conf->disable);
+  CHECK_STR_EQ_FREE1(format("a:b c:%s", user), conf->extra_files_to_hash);
+  CHECK(conf->file_clone);
+  CHECK(conf->hard_link);
+  CHECK(!conf->hash_dir);
+  CHECK_STR_EQ("a:b/c", conf->ignore_headers_in_manifest);
+  CHECK(conf->keep_comments_cpp);
+  CHECK_DOUBLE_EQ(1.0, conf->limit_multiple);
+  CHECK_STR_EQ_FREE1(format("%s%s", user, user), conf->log_file);
+  CHECK_INT_EQ(17, conf->max_files);
+  CHECK_INT_EQ(123 * 1000 * 1000, conf->max_size);
+  CHECK_STR_EQ_FREE1(format("%s.x", user), conf->path);
+  CHECK(conf->pch_external_checksum);
+  CHECK_STR_EQ_FREE1(format("x%s", user), conf->prefix_command);
+  CHECK_STR_EQ("y", conf->prefix_command_cpp);
+  CHECK(conf->read_only);
+  CHECK(conf->read_only_direct);
+  CHECK(conf->recache);
+  CHECK(!conf->run_second_cpp);
+  CHECK_INT_EQ(SLOPPY_INCLUDE_FILE_MTIME | SLOPPY_INCLUDE_FILE_CTIME
+                 | SLOPPY_FILE_MACRO | SLOPPY_TIME_MACROS
+                 | SLOPPY_FILE_STAT_MATCHES | SLOPPY_FILE_STAT_MATCHES_CTIME
+                 | SLOPPY_SYSTEM_HEADERS | SLOPPY_PCH_DEFINES
+                 | SLOPPY_CLANG_INDEX_STORE,
+               conf->sloppiness);
+  CHECK(!conf->stats);
+  CHECK_STR_EQ_FREE1(format("%s_foo", user), conf->temporary_dir);
+  CHECK_INT_EQ(0777, conf->umask);
+  CHECK(conf->unify);
+
+  conf_free(conf);
 }
 
 TEST(conf_read_with_missing_equal_sign)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-       create_file("ccache.conf", "no equal sign");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, 0);
-       CHECK_STR_EQ_FREE2("ccache.conf:1: missing equal sign",
-                          errmsg);
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+  create_file("ccache.conf", "no equal sign");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(errno, 0);
+  CHECK_STR_EQ_FREE2("ccache.conf:1: missing equal sign", errmsg);
+  conf_free(conf);
 }
 
 TEST(conf_read_with_unknown_config_key)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-       create_file("ccache.conf", "# Comment\nfoo = bar");
-       CHECK(conf_read(conf, "ccache.conf", &errmsg));
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+  create_file("ccache.conf", "# Comment\nfoo = bar");
+  CHECK(conf_read(conf, "ccache.conf", &errmsg));
+  conf_free(conf);
 }
 
 TEST(conf_read_invalid_bool)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-
-       create_file("ccache.conf", "disable=");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, 0);
-       CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"\"",
-                          errmsg);
-
-       create_file("ccache.conf", "disable=foo");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, 0);
-       CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"foo\"",
-                          errmsg);
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+
+  create_file("ccache.conf", "disable=");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(errno, 0);
+  CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"\"", errmsg);
+
+  create_file("ccache.conf", "disable=foo");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(errno, 0);
+  CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"foo\"", errmsg);
+  conf_free(conf);
 }
 
 TEST(conf_read_invalid_env_string)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-       create_file("ccache.conf", "base_dir = ${foo");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, 0);
-       CHECK_STR_EQ_FREE2("ccache.conf:1: syntax error: missing '}' after \"foo\"",
-                          errmsg);
-       // Other cases tested in test_util.c.
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+  create_file("ccache.conf", "base_dir = ${foo");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(errno, 0);
+  CHECK_STR_EQ_FREE2("ccache.conf:1: syntax error: missing '}' after \"foo\"",
+                     errmsg);
+  // Other cases tested in test_util.c.
+  conf_free(conf);
 }
 
 TEST(conf_read_empty_umask)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-       create_file("ccache.conf", "umask = ");
-       CHECK(conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(conf->umask, UINT_MAX);
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+  create_file("ccache.conf", "umask = ");
+  CHECK(conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(conf->umask, UINT_MAX);
+  conf_free(conf);
 }
 
 TEST(conf_read_invalid_size)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-       create_file("ccache.conf", "max_size = foo");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, 0);
-       CHECK_STR_EQ_FREE2("ccache.conf:1: invalid size: \"foo\"",
-                          errmsg);
-       // Other cases tested in test_util.c.
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+  create_file("ccache.conf", "max_size = foo");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(errno, 0);
+  CHECK_STR_EQ_FREE2("ccache.conf:1: invalid size: \"foo\"", errmsg);
+  // Other cases tested in test_util.c.
+  conf_free(conf);
 }
 
 TEST(conf_read_invalid_sloppiness)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-       create_file("ccache.conf", "sloppiness = file_macro, foo");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, 0);
-       CHECK_STR_EQ_FREE2("ccache.conf:1: unknown sloppiness: \"foo\"",
-                          errmsg);
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+  create_file("ccache.conf", "sloppiness = file_macro, foo");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(errno, 0);
+  CHECK_STR_EQ_FREE2("ccache.conf:1: unknown sloppiness: \"foo\"", errmsg);
+  conf_free(conf);
 }
 
 TEST(conf_read_invalid_unsigned)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-
-       create_file("ccache.conf", "max_files =");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, 0);
-       CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"\"",
-                          errmsg);
-
-       create_file("ccache.conf", "max_files = -42");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"-42\"",
-                          errmsg);
-
-       create_file("ccache.conf", "max_files = foo");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"foo\"",
-                          errmsg);
-
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+
+  create_file("ccache.conf", "max_files =");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(errno, 0);
+  CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"\"", errmsg);
+
+  create_file("ccache.conf", "max_files = -42");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"-42\"",
+                     errmsg);
+
+  create_file("ccache.conf", "max_files = foo");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"foo\"",
+                     errmsg);
+
+  conf_free(conf);
 }
 
 TEST(conf_read_missing_config_file)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, ENOENT);
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_INT_EQ(errno, ENOENT);
+  conf_free(conf);
 }
 
 TEST(verify_absolute_base_dir)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
+  struct conf* conf = conf_create();
+  char* errmsg;
 
-       create_file("ccache.conf", "base_dir = relative/path");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_STR_EQ_FREE2("ccache.conf:1: not an absolute path: \"relative/path\"",
-                          errmsg);
+  create_file("ccache.conf", "base_dir = relative/path");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_STR_EQ_FREE2("ccache.conf:1: not an absolute path: \"relative/path\"",
+                     errmsg);
 
-       create_file("ccache.conf", "base_dir =");
-       CHECK(conf_read(conf, "ccache.conf", &errmsg));
+  create_file("ccache.conf", "base_dir =");
+  CHECK(conf_read(conf, "ccache.conf", &errmsg));
 
-       conf_free(conf);
+  conf_free(conf);
 }
 
 TEST(verify_dir_levels)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-
-       create_file("ccache.conf", "cache_dir_levels = 0");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_STR_EQ_FREE2(
-               "ccache.conf:1: cache directory levels must be between 1 and 8",
-               errmsg);
-       create_file("ccache.conf", "cache_dir_levels = 9");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_STR_EQ_FREE2(
-               "ccache.conf:1: cache directory levels must be between 1 and 8",
-               errmsg);
-
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+
+  create_file("ccache.conf", "cache_dir_levels = 0");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_STR_EQ_FREE2(
+    "ccache.conf:1: cache directory levels must be between 1 and 8", errmsg);
+  create_file("ccache.conf", "cache_dir_levels = 9");
+  CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+  CHECK_STR_EQ_FREE2(
+    "ccache.conf:1: cache directory levels must be between 1 and 8", errmsg);
+
+  conf_free(conf);
 }
 
 TEST(conf_update_from_environment)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
+  struct conf* conf = conf_create();
+  char* errmsg;
 
-       putenv(COMPRESS_1_ENV);
-       CHECK(conf_update_from_environment(conf, &errmsg));
-       CHECK(conf->compression);
+  putenv(COMPRESS_1_ENV);
+  CHECK(conf_update_from_environment(conf, &errmsg));
+  CHECK(conf->compression);
 
-       x_unsetenv("CCACHE_COMPRESS");
-       putenv(NOCOMPRESS_1_ENV);
-       CHECK(conf_update_from_environment(conf, &errmsg));
-       CHECK(!conf->compression);
+  x_unsetenv("CCACHE_COMPRESS");
+  putenv(NOCOMPRESS_1_ENV);
+  CHECK(conf_update_from_environment(conf, &errmsg));
+  CHECK(!conf->compression);
 
-       conf_free(conf);
+  conf_free(conf);
 }
 
 TEST(conf_set_new_value)
 {
-       char *errmsg;
-       char *data;
-
-       create_file("ccache.conf", "path = vanilla\n");
-       CHECKM(conf_set_value_in_file("ccache.conf", "compiler", "chocolate",
-                                     &errmsg),
-              errmsg);
-       data = read_text_file("ccache.conf", 0);
-       CHECK(data);
-       CHECK_STR_EQ_FREE2("path = vanilla\ncompiler = chocolate\n", data);
+  char* errmsg;
+  char* data;
+
+  create_file("ccache.conf", "path = vanilla\n");
+  CHECKM(
+    conf_set_value_in_file("ccache.conf", "compiler", "chocolate", &errmsg),
+    errmsg);
+  data = read_text_file("ccache.conf", 0);
+  CHECK(data);
+  CHECK_STR_EQ_FREE2("path = vanilla\ncompiler = chocolate\n", data);
 }
 
 TEST(conf_set_existing_value)
 {
-       char *errmsg;
-       char *data;
-
-       create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
-       CHECKM(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg),
-              errmsg);
-       data = read_text_file("ccache.conf", 0);
-       CHECK(data);
-       CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
+  char* errmsg;
+  char* data;
+
+  create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
+  CHECKM(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg),
+         errmsg);
+  data = read_text_file("ccache.conf", 0);
+  CHECK(data);
+  CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
 }
 
 TEST(conf_set_unknown_option)
 {
-       char *errmsg;
-       char *data;
+  char* errmsg;
+  char* data;
 
-       create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
-       CHECKM(!conf_set_value_in_file("ccache.conf", "foo", "bar", &errmsg),
-              errmsg);
-       CHECK_STR_EQ_FREE2("unknown configuration option \"foo\"", errmsg);
+  create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
+  CHECKM(!conf_set_value_in_file("ccache.conf", "foo", "bar", &errmsg), errmsg);
+  CHECK_STR_EQ_FREE2("unknown configuration option \"foo\"", errmsg);
 
-       data = read_text_file("ccache.conf", 0);
-       CHECK(data);
-       CHECK_STR_EQ_FREE2("path = chocolate\nstats = chocolate\n", data);
+  data = read_text_file("ccache.conf", 0);
+  CHECK(data);
+  CHECK_STR_EQ_FREE2("path = chocolate\nstats = chocolate\n", data);
 }
 
 TEST(conf_print_existing_value)
 {
-       struct conf *conf = conf_create();
-       conf->max_files = 42;
-       char *errmsg;
-       {
-               FILE *log = fopen("log", "w");
-               CHECK(log);
-               CHECK(conf_print_value(conf, "max_files", log, &errmsg));
-               fclose(log);
-       }
-       {
-               FILE *log = fopen("log", "r");
-               CHECK(log);
-               char buf[100];
-               CHECK(fgets(buf, sizeof(buf), log));
-               CHECK_STR_EQ("42\n", buf);
-               fclose(log);
-       }
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  conf->max_files = 42;
+  char* errmsg;
+  {
+    FILE* log = fopen("log", "w");
+    CHECK(log);
+    CHECK(conf_print_value(conf, "max_files", log, &errmsg));
+    fclose(log);
+  }
+  {
+    FILE* log = fopen("log", "r");
+    CHECK(log);
+    char buf[100];
+    CHECK(fgets(buf, sizeof(buf), log));
+    CHECK_STR_EQ("42\n", buf);
+    fclose(log);
+  }
+  conf_free(conf);
 }
 
 TEST(conf_print_unknown_value)
 {
-       struct conf *conf = conf_create();
-       char *errmsg;
-       {
-               FILE *log = fopen("log", "w");
-               CHECK(log);
-               CHECK(!conf_print_value(conf, "foo", log, &errmsg));
-               CHECK_STR_EQ_FREE2("unknown configuration option \"foo\"",
-                                  errmsg);
-               fclose(log);
-       }
-       {
-               FILE *log = fopen("log", "r");
-               CHECK(log);
-               char buf[100];
-               CHECK(!fgets(buf, sizeof(buf), log));
-               fclose(log);
-       }
-       conf_free(conf);
+  struct conf* conf = conf_create();
+  char* errmsg;
+  {
+    FILE* log = fopen("log", "w");
+    CHECK(log);
+    CHECK(!conf_print_value(conf, "foo", log, &errmsg));
+    CHECK_STR_EQ_FREE2("unknown configuration option \"foo\"", errmsg);
+    fclose(log);
+  }
+  {
+    FILE* log = fopen("log", "r");
+    CHECK(log);
+    char buf[100];
+    CHECK(!fgets(buf, sizeof(buf), log));
+    fclose(log);
+  }
+  conf_free(conf);
 }
 
 TEST(conf_print_items)
 {
-       struct conf* conf = conf_create();
-       conf->base_dir = x_strdup("bd");
-       conf->cache_dir = x_strdup("cd");
-       conf->cache_dir_levels = 7;
-       conf->compiler = x_strdup("c");
-       conf->compiler_check = x_strdup("cc");
-       conf->compression = true;
-       conf->compression_level = 8;
-       conf->cpp_extension = x_strdup("ce");
-       conf->debug = false;
-       conf->depend_mode = true;
-       conf->direct_mode = false;
-       conf->disable = true;
-       conf->extra_files_to_hash = x_strdup("efth");
-       conf->file_clone = true;
-       conf->hard_link = true;
-       conf->hash_dir = false;
-       conf->ignore_headers_in_manifest = x_strdup("ihim");
-       conf->keep_comments_cpp = true;
-       conf->limit_multiple = 0.0;
-       conf->log_file = x_strdup("lf");
-       conf->max_files = 4711;
-       conf->max_size = 98.7 * 1000 * 1000;
-       conf->path = x_strdup("p");
-       conf->pch_external_checksum = true;
-       conf->prefix_command = x_strdup("pc");
-       conf->prefix_command_cpp = x_strdup("pcc");
-       conf->read_only = true;
-       conf->read_only_direct = true;
-       conf->recache = true;
-       conf->run_second_cpp = false;
-       conf->sloppiness =
-               SLOPPY_FILE_MACRO | SLOPPY_INCLUDE_FILE_MTIME | SLOPPY_INCLUDE_FILE_CTIME
-               | SLOPPY_TIME_MACROS | SLOPPY_FILE_STAT_MATCHES
-               | SLOPPY_FILE_STAT_MATCHES_CTIME | SLOPPY_PCH_DEFINES
-               | SLOPPY_SYSTEM_HEADERS | SLOPPY_CLANG_INDEX_STORE;
-       conf->stats = false;
-       conf->temporary_dir = x_strdup("td");
-       conf->umask = 022;
-       conf->unify = true;
-
-       conf->item_origins =
-               static_cast<const char**>(x_malloc(N_CONFIG_ITEMS * sizeof(char *)));
-       for (size_t i = 0; i < N_CONFIG_ITEMS; ++i) {
+  struct conf* conf = conf_create();
+  conf->base_dir = x_strdup("bd");
+  conf->cache_dir = x_strdup("cd");
+  conf->cache_dir_levels = 7;
+  conf->compiler = x_strdup("c");
+  conf->compiler_check = x_strdup("cc");
+  conf->compression = true;
+  conf->compression_level = 8;
+  conf->cpp_extension = x_strdup("ce");
+  conf->debug = false;
+  conf->depend_mode = true;
+  conf->direct_mode = false;
+  conf->disable = true;
+  conf->extra_files_to_hash = x_strdup("efth");
+  conf->file_clone = true;
+  conf->hard_link = true;
+  conf->hash_dir = false;
+  conf->ignore_headers_in_manifest = x_strdup("ihim");
+  conf->keep_comments_cpp = true;
+  conf->limit_multiple = 0.0;
+  conf->log_file = x_strdup("lf");
+  conf->max_files = 4711;
+  conf->max_size = 98.7 * 1000 * 1000;
+  conf->path = x_strdup("p");
+  conf->pch_external_checksum = true;
+  conf->prefix_command = x_strdup("pc");
+  conf->prefix_command_cpp = x_strdup("pcc");
+  conf->read_only = true;
+  conf->read_only_direct = true;
+  conf->recache = true;
+  conf->run_second_cpp = false;
+  conf->sloppiness = SLOPPY_FILE_MACRO | SLOPPY_INCLUDE_FILE_MTIME
+                     | SLOPPY_INCLUDE_FILE_CTIME | SLOPPY_TIME_MACROS
+                     | SLOPPY_FILE_STAT_MATCHES | SLOPPY_FILE_STAT_MATCHES_CTIME
+                     | SLOPPY_PCH_DEFINES | SLOPPY_SYSTEM_HEADERS
+                     | SLOPPY_CLANG_INDEX_STORE;
+  conf->stats = false;
+  conf->temporary_dir = x_strdup("td");
+  conf->umask = 022;
+  conf->unify = true;
+
+  conf->item_origins =
+    static_cast<const char**>(x_malloc(N_CONFIG_ITEMS * sizeof(char*)));
+  for (size_t i = 0; i < N_CONFIG_ITEMS; ++i) {
 #ifndef __MINGW32__
-               conf->item_origins[i] = format("origin%zu", i);
+    conf->item_origins[i] = format("origin%zu", i);
 #else
-               conf->item_origins[i] = format("origin%u", (unsigned) i);
+    conf->item_origins[i] = format("origin%u", (unsigned)i);
 #endif
-       }
-
-       size_t n = 0;
-       conf_print_items(conf, conf_item_receiver, NULL);
-       CHECK_INT_EQ(N_CONFIG_ITEMS, n_received_conf_items);
-       CHECK_STR_EQ("base_dir = bd", received_conf_items[n++].descr);
-       CHECK_STR_EQ("cache_dir = cd", received_conf_items[n++].descr);
-       CHECK_STR_EQ("cache_dir_levels = 7", received_conf_items[n++].descr);
-       CHECK_STR_EQ("compiler = c", received_conf_items[n++].descr);
-       CHECK_STR_EQ("compiler_check = cc", received_conf_items[n++].descr);
-       CHECK_STR_EQ("compression = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("compression_level = 8", received_conf_items[n++].descr);
-       CHECK_STR_EQ("cpp_extension = ce", received_conf_items[n++].descr);
-       CHECK_STR_EQ("debug = false", received_conf_items[n++].descr);
-       CHECK_STR_EQ("depend_mode = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("direct_mode = false", received_conf_items[n++].descr);
-       CHECK_STR_EQ("disable = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("extra_files_to_hash = efth", received_conf_items[n++].descr);
-       CHECK_STR_EQ("file_clone = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("hard_link = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("hash_dir = false", received_conf_items[n++].descr);
-       CHECK_STR_EQ("ignore_headers_in_manifest = ihim",
-                    received_conf_items[n++].descr);
-       CHECK_STR_EQ("keep_comments_cpp = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("limit_multiple = 0.0", received_conf_items[n++].descr);
-       CHECK_STR_EQ("log_file = lf", received_conf_items[n++].descr);
-       CHECK_STR_EQ("max_files = 4711", received_conf_items[n++].descr);
-       CHECK_STR_EQ("max_size = 98.7M", received_conf_items[n++].descr);
-       CHECK_STR_EQ("path = p", received_conf_items[n++].descr);
-       CHECK_STR_EQ("pch_external_checksum = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("prefix_command = pc", received_conf_items[n++].descr);
-       CHECK_STR_EQ("prefix_command_cpp = pcc", received_conf_items[n++].descr);
-       CHECK_STR_EQ("read_only = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("read_only_direct = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
-       CHECK_STR_EQ("run_second_cpp = false", received_conf_items[n++].descr);
-       CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
-                    " include_file_ctime, time_macros, pch_defines,"
-                    " file_stat_matches, file_stat_matches_ctime, system_headers,"
-                    " clang_index_store",
-                    received_conf_items[n++].descr);
-       CHECK_STR_EQ("stats = false", received_conf_items[n++].descr);
-       CHECK_STR_EQ("temporary_dir = td", received_conf_items[n++].descr);
-       CHECK_STR_EQ("umask = 022", received_conf_items[n++].descr);
-       CHECK_STR_EQ("unify = true", received_conf_items[n++].descr);
-
-       for (size_t i = 0; i < N_CONFIG_ITEMS; ++i) {
+  }
+
+  size_t n = 0;
+  conf_print_items(conf, conf_item_receiver, NULL);
+  CHECK_INT_EQ(N_CONFIG_ITEMS, n_received_conf_items);
+  CHECK_STR_EQ("base_dir = bd", received_conf_items[n++].descr);
+  CHECK_STR_EQ("cache_dir = cd", received_conf_items[n++].descr);
+  CHECK_STR_EQ("cache_dir_levels = 7", received_conf_items[n++].descr);
+  CHECK_STR_EQ("compiler = c", received_conf_items[n++].descr);
+  CHECK_STR_EQ("compiler_check = cc", received_conf_items[n++].descr);
+  CHECK_STR_EQ("compression = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("compression_level = 8", received_conf_items[n++].descr);
+  CHECK_STR_EQ("cpp_extension = ce", received_conf_items[n++].descr);
+  CHECK_STR_EQ("debug = false", received_conf_items[n++].descr);
+  CHECK_STR_EQ("depend_mode = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("direct_mode = false", received_conf_items[n++].descr);
+  CHECK_STR_EQ("disable = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("extra_files_to_hash = efth", received_conf_items[n++].descr);
+  CHECK_STR_EQ("file_clone = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("hard_link = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("hash_dir = false", received_conf_items[n++].descr);
+  CHECK_STR_EQ("ignore_headers_in_manifest = ihim",
+               received_conf_items[n++].descr);
+  CHECK_STR_EQ("keep_comments_cpp = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("limit_multiple = 0.0", received_conf_items[n++].descr);
+  CHECK_STR_EQ("log_file = lf", received_conf_items[n++].descr);
+  CHECK_STR_EQ("max_files = 4711", received_conf_items[n++].descr);
+  CHECK_STR_EQ("max_size = 98.7M", received_conf_items[n++].descr);
+  CHECK_STR_EQ("path = p", received_conf_items[n++].descr);
+  CHECK_STR_EQ("pch_external_checksum = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("prefix_command = pc", received_conf_items[n++].descr);
+  CHECK_STR_EQ("prefix_command_cpp = pcc", received_conf_items[n++].descr);
+  CHECK_STR_EQ("read_only = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("read_only_direct = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
+  CHECK_STR_EQ("run_second_cpp = false", received_conf_items[n++].descr);
+  CHECK_STR_EQ(
+    "sloppiness = file_macro, include_file_mtime,"
+    " include_file_ctime, time_macros, pch_defines,"
+    " file_stat_matches, file_stat_matches_ctime, system_headers,"
+    " clang_index_store",
+    received_conf_items[n++].descr);
+  CHECK_STR_EQ("stats = false", received_conf_items[n++].descr);
+  CHECK_STR_EQ("temporary_dir = td", received_conf_items[n++].descr);
+  CHECK_STR_EQ("umask = 022", received_conf_items[n++].descr);
+  CHECK_STR_EQ("unify = true", received_conf_items[n++].descr);
+
+  for (size_t i = 0; i < N_CONFIG_ITEMS; ++i) {
 #ifndef __MINGW32__
-               char *expected = format("origin%zu", i);
+    char* expected = format("origin%zu", i);
 #else
-               char *expected = format("origin%u", (unsigned) i);
+    char* expected = format("origin%u", (unsigned)i);
 #endif
-               CHECK_STR_EQ_FREE1(expected, received_conf_items[i].origin);
-       }
+    CHECK_STR_EQ_FREE1(expected, received_conf_items[i].origin);
+  }
 
-       free_received_conf_items();
-       conf_free(conf);
+  free_received_conf_items();
+  conf_free(conf);
 }
 
 TEST_SUITE_END
index 7f07006da9a41ada3ca31cf768998789a74511bc..e84168901746d45213d6c2b435106d967d32244e 100644 (file)
@@ -25,38 +25,38 @@ TEST_SUITE(counters)
 
 TEST(counters_init_0_should_allocate_0)
 {
-       struct counters *counters = counters_init(0);
+  struct counters* counters = counters_init(0);
 
-       CHECK_INT_EQ(0, counters->allocated);
-       CHECK_INT_EQ(0, counters->size);
+  CHECK_INT_EQ(0, counters->allocated);
+  CHECK_INT_EQ(0, counters->size);
 
-       counters_free(counters);
+  counters_free(counters);
 }
 
 TEST(counters_init_7_should_allocate_32)
 {
-       int i;
-       struct counters *counters = counters_init(7);
+  int i;
+  struct counters* counters = counters_init(7);
 
-       CHECK_INT_EQ(32, counters->allocated);
-       CHECK_INT_EQ(7, counters->size);
-       for (i = 0; i < 7; i++) {
-               CHECK_INT_EQ(0, counters->data[i]);
-       }
+  CHECK_INT_EQ(32, counters->allocated);
+  CHECK_INT_EQ(7, counters->size);
+  for (i = 0; i < 7; i++) {
+    CHECK_INT_EQ(0, counters->data[i]);
+  }
 
-       counters_free(counters);
+  counters_free(counters);
 }
 
 TEST(counters_resize_50_should_allocate_96)
 {
-       struct counters *counters = counters_init(0);
+  struct counters* counters = counters_init(0);
 
-       CHECK_INT_EQ(0, counters->allocated);
-       counters_resize(counters, 50);
-       CHECK_INT_EQ(50, counters->size);
-       CHECK_INT_EQ(96, counters->allocated);
+  CHECK_INT_EQ(0, counters->allocated);
+  counters_resize(counters, 50);
+  CHECK_INT_EQ(50, counters->size);
+  CHECK_INT_EQ(96, counters->allocated);
 
-       counters_free(counters);
+  counters_free(counters);
 }
 
 TEST_SUITE_END
index df3bc8b92400254adc9f8a29553cd90de4cbf5b4..6d8795c467aa8d263ea3a90def9d68babebdfcd5 100644 (file)
@@ -26,81 +26,81 @@ TEST_SUITE(hash)
 
 TEST(test_known_strings)
 {
-       char d[DIGEST_STRING_BUFFER_SIZE];
+  char d[DIGEST_STRING_BUFFER_SIZE];
 
-       {
-               struct hash *h = hash_init();
-               hash_string(h, "");
-               hash_result_as_string(h, d);
-               CHECK_STR_EQ("3345524abf6bbe1809449224b5972c41790b6cf2", d);
-               hash_free(h);
-       }
+  {
+    struct hash* h = hash_init();
+    hash_string(h, "");
+    hash_result_as_string(h, d);
+    CHECK_STR_EQ("3345524abf6bbe1809449224b5972c41790b6cf2", d);
+    hash_free(h);
+  }
 
-       {
-               struct hash *h = hash_init();
-               hash_string(h, "a");
-               hash_result_as_string(h, d);
-               CHECK_STR_EQ("948caa2db61bc4cdb4faf7740cd491f195043914", d);
-               hash_free(h);
-       }
+  {
+    struct hash* h = hash_init();
+    hash_string(h, "a");
+    hash_result_as_string(h, d);
+    CHECK_STR_EQ("948caa2db61bc4cdb4faf7740cd491f195043914", d);
+    hash_free(h);
+  }
 
-       {
-               struct hash *h = hash_init();
-               hash_string(h, "message digest");
-               hash_result_as_string(h, d);
-               CHECK_STR_EQ("6bfec6f65e52962be863d6ea1005fc5e4cc8478c", d);
-               hash_free(h);
-       }
+  {
+    struct hash* h = hash_init();
+    hash_string(h, "message digest");
+    hash_result_as_string(h, d);
+    CHECK_STR_EQ("6bfec6f65e52962be863d6ea1005fc5e4cc8478c", d);
+    hash_free(h);
+  }
 
-       {
-               struct hash *h = hash_init();
-               hash_string(
-                       h,
-                       "12345678901234567890123456789012345678901234567890123456789012345678901"
-                       "234567890");
-               hash_result_as_string(h, d);
-               CHECK_STR_EQ("c2be0e534a67d25947f0c7e78527b2f82abd260f", d);
-               hash_free(h);
-       }
+  {
+    struct hash* h = hash_init();
+    hash_string(
+      h,
+      "1234567890123456789012345678901234567890123456789012345678901234567890"
+      "1"
+      "234567890");
+    hash_result_as_string(h, d);
+    CHECK_STR_EQ("c2be0e534a67d25947f0c7e78527b2f82abd260f", d);
+    hash_free(h);
+  }
 }
 
 TEST(hash_result_should_not_alter_state)
 {
-       char d[DIGEST_STRING_BUFFER_SIZE];
-       struct hash *h = hash_init();
-       hash_string(h, "message");
-       hash_result_as_string(h, d);
-       hash_string(h, " digest");
-       hash_result_as_string(h, d);
-       CHECK_STR_EQ("6bfec6f65e52962be863d6ea1005fc5e4cc8478c", d);
-       hash_free(h);
+  char d[DIGEST_STRING_BUFFER_SIZE];
+  struct hash* h = hash_init();
+  hash_string(h, "message");
+  hash_result_as_string(h, d);
+  hash_string(h, " digest");
+  hash_result_as_string(h, d);
+  CHECK_STR_EQ("6bfec6f65e52962be863d6ea1005fc5e4cc8478c", d);
+  hash_free(h);
 }
 
 TEST(hash_result_should_be_idempotent)
 {
-       char d[DIGEST_STRING_BUFFER_SIZE];
-       struct hash *h = hash_init();
-       hash_string(h, "");
-       hash_result_as_string(h, d);
-       CHECK_STR_EQ("3345524abf6bbe1809449224b5972c41790b6cf2", d);
-       hash_result_as_string(h, d);
-       CHECK_STR_EQ("3345524abf6bbe1809449224b5972c41790b6cf2", d);
+  char d[DIGEST_STRING_BUFFER_SIZE];
+  struct hash* h = hash_init();
+  hash_string(h, "");
+  hash_result_as_string(h, d);
+  CHECK_STR_EQ("3345524abf6bbe1809449224b5972c41790b6cf2", d);
+  hash_result_as_string(h, d);
+  CHECK_STR_EQ("3345524abf6bbe1809449224b5972c41790b6cf2", d);
 
-       hash_free(h);
+  hash_free(h);
 }
 
 TEST(hash_result_as_bytes)
 {
-       struct hash *h = hash_init();
-       hash_string(h, "message digest");
-       struct digest d;
-       hash_result_as_bytes(h, &d);
-       uint8_t expected[sizeof(d.bytes)] = {
-               0x6b, 0xfe, 0xc6, 0xf6, 0x5e, 0x52, 0x96, 0x2b, 0xe8, 0x63, 0xd6, 0xea,
-               0x10, 0x05, 0xfc, 0x5e, 0x4c, 0xc8, 0x47, 0x8c
-       };
-       CHECK_DATA_EQ(d.bytes, expected, sizeof(d.bytes));
-       hash_free(h);
+  struct hash* h = hash_init();
+  hash_string(h, "message digest");
+  struct digest d;
+  hash_result_as_bytes(h, &d);
+  uint8_t expected[sizeof(d.bytes)] = {0x6b, 0xfe, 0xc6, 0xf6, 0x5e, 0x52, 0x96,
+                                       0x2b, 0xe8, 0x63, 0xd6, 0xea, 0x10, 0x05,
+                                       0xfc, 0x5e, 0x4c, 0xc8, 0x47, 0x8c};
+  CHECK_DATA_EQ(d.bytes, expected, sizeof(d.bytes));
+  hash_free(h);
 }
 
 TEST_SUITE_END
index a7432281b81502b93584c865d60100bfb017f302..c42911b72939bd9e8a0401486b86c3be149a5271 100644 (file)
@@ -27,222 +27,220 @@ TEST_SUITE(hashutil)
 
 TEST(hash_command_output_simple)
 {
-       char d1[DIGEST_STRING_BUFFER_SIZE];
-       char d2[DIGEST_STRING_BUFFER_SIZE];
+  char d1[DIGEST_STRING_BUFFER_SIZE];
+  char d2[DIGEST_STRING_BUFFER_SIZE];
 
-       struct hash *h1 = hash_init();
-       struct hash *h2 = hash_init();
+  struct hash* h1 = hash_init();
+  struct hash* h2 = hash_init();
 
-       CHECK(hash_command_output(h1, "echo", "not used"));
-       CHECK(hash_command_output(h2, "echo", "not used"));
-       hash_result_as_string(h1, d1);
-       hash_result_as_string(h2, d2);
-       CHECK_STR_EQ(d1, d2);
+  CHECK(hash_command_output(h1, "echo", "not used"));
+  CHECK(hash_command_output(h2, "echo", "not used"));
+  hash_result_as_string(h1, d1);
+  hash_result_as_string(h2, d2);
+  CHECK_STR_EQ(d1, d2);
 
-       hash_free(h2);
-       hash_free(h1);
+  hash_free(h2);
+  hash_free(h1);
 }
 
 TEST(hash_command_output_space_removal)
 {
-       char d1[DIGEST_STRING_BUFFER_SIZE];
-       char d2[DIGEST_STRING_BUFFER_SIZE];
+  char d1[DIGEST_STRING_BUFFER_SIZE];
+  char d2[DIGEST_STRING_BUFFER_SIZE];
 
-       struct hash *h1 = hash_init();
-       struct hash *h2 = hash_init();
+  struct hash* h1 = hash_init();
+  struct hash* h2 = hash_init();
 
-       CHECK(hash_command_output(h1, "echo", "not used"));
-       CHECK(hash_command_output(h2, " echo ", "not used"));
-       hash_result_as_string(h1, d1);
-       hash_result_as_string(h2, d2);
-       CHECK_STR_EQ(d1, d2);
+  CHECK(hash_command_output(h1, "echo", "not used"));
+  CHECK(hash_command_output(h2, " echo ", "not used"));
+  hash_result_as_string(h1, d1);
+  hash_result_as_string(h2, d2);
+  CHECK_STR_EQ(d1, d2);
 
-       hash_free(h2);
-       hash_free(h1);
+  hash_free(h2);
+  hash_free(h1);
 }
 
 TEST(hash_command_output_hash_inequality)
 {
-       char d1[DIGEST_STRING_BUFFER_SIZE];
-       char d2[DIGEST_STRING_BUFFER_SIZE];
+  char d1[DIGEST_STRING_BUFFER_SIZE];
+  char d2[DIGEST_STRING_BUFFER_SIZE];
 
-       struct hash *h1 = hash_init();
-       struct hash *h2 = hash_init();
+  struct hash* h1 = hash_init();
+  struct hash* h2 = hash_init();
 
-       CHECK(hash_command_output(h1, "echo foo", "not used"));
-       CHECK(hash_command_output(h2, "echo bar", "not used"));
-       hash_result_as_string(h1, d1);
-       hash_result_as_string(h2, d2);
-       CHECK(!str_eq(d1, d2));
+  CHECK(hash_command_output(h1, "echo foo", "not used"));
+  CHECK(hash_command_output(h2, "echo bar", "not used"));
+  hash_result_as_string(h1, d1);
+  hash_result_as_string(h2, d2);
+  CHECK(!str_eq(d1, d2));
 
-       hash_free(h2);
-       hash_free(h1);
+  hash_free(h2);
+  hash_free(h1);
 }
 
 TEST(hash_command_output_compiler_substitution)
 {
-       char d1[DIGEST_STRING_BUFFER_SIZE];
-       char d2[DIGEST_STRING_BUFFER_SIZE];
+  char d1[DIGEST_STRING_BUFFER_SIZE];
+  char d2[DIGEST_STRING_BUFFER_SIZE];
 
-       struct hash *h1 = hash_init();
-       struct hash *h2 = hash_init();
+  struct hash* h1 = hash_init();
+  struct hash* h2 = hash_init();
 
-       CHECK(hash_command_output(h1, "echo foo", "not used"));
-       CHECK(hash_command_output(h2, "%compiler% foo", "echo"));
-       hash_result_as_string(h1, d1);
-       hash_result_as_string(h2, d2);
-       CHECK_STR_EQ(d1, d2);
+  CHECK(hash_command_output(h1, "echo foo", "not used"));
+  CHECK(hash_command_output(h2, "%compiler% foo", "echo"));
+  hash_result_as_string(h1, d1);
+  hash_result_as_string(h2, d2);
+  CHECK_STR_EQ(d1, d2);
 
-       hash_free(h2);
-       hash_free(h1);
+  hash_free(h2);
+  hash_free(h1);
 }
 
 TEST(hash_command_output_stdout_versus_stderr)
 {
-       char d1[DIGEST_STRING_BUFFER_SIZE];
-       char d2[DIGEST_STRING_BUFFER_SIZE];
+  char d1[DIGEST_STRING_BUFFER_SIZE];
+  char d2[DIGEST_STRING_BUFFER_SIZE];
 
-       struct hash *h1 = hash_init();
-       struct hash *h2 = hash_init();
+  struct hash* h1 = hash_init();
+  struct hash* h2 = hash_init();
 
 #ifndef _WIN32
-       create_file("stderr.sh", "#!/bin/sh\necho foo >&2\n");
-       chmod("stderr.sh", 0555);
-       CHECK(hash_command_output(h1, "echo foo", "not used"));
-       CHECK(hash_command_output(h2, "./stderr.sh", "not used"));
+  create_file("stderr.sh", "#!/bin/sh\necho foo >&2\n");
+  chmod("stderr.sh", 0555);
+  CHECK(hash_command_output(h1, "echo foo", "not used"));
+  CHECK(hash_command_output(h2, "./stderr.sh", "not used"));
 #else
-       create_file("stderr.bat", "@echo off\r\necho foo>&2\r\n");
-       CHECK(hash_command_output(h1, "echo foo", "not used"));
-       CHECK(hash_command_output(h2, "stderr.bat", "not used"));
+  create_file("stderr.bat", "@echo off\r\necho foo>&2\r\n");
+  CHECK(hash_command_output(h1, "echo foo", "not used"));
+  CHECK(hash_command_output(h2, "stderr.bat", "not used"));
 #endif
-       hash_result_as_string(h1, d1);
-       hash_result_as_string(h2, d2);
-       CHECK_STR_EQ(d1, d2);
+  hash_result_as_string(h1, d1);
+  hash_result_as_string(h2, d2);
+  CHECK_STR_EQ(d1, d2);
 
-       hash_free(h2);
-       hash_free(h1);
+  hash_free(h2);
+  hash_free(h1);
 }
 
 TEST(hash_multicommand_output)
 {
-       char d1[DIGEST_STRING_BUFFER_SIZE];
-       char d2[DIGEST_STRING_BUFFER_SIZE];
+  char d1[DIGEST_STRING_BUFFER_SIZE];
+  char d2[DIGEST_STRING_BUFFER_SIZE];
 
-       struct hash *h1 = hash_init();
-       struct hash *h2 = hash_init();
+  struct hash* h1 = hash_init();
+  struct hash* h2 = hash_init();
 
 #ifndef _WIN32
-       create_file("foo.sh", "#!/bin/sh\necho foo\necho bar\n");
-       chmod("foo.sh", 0555);
-       CHECK(hash_multicommand_output(h2, "echo foo; echo bar", "not used"));
-       CHECK(hash_multicommand_output(h1, "./foo.sh", "not used"));
+  create_file("foo.sh", "#!/bin/sh\necho foo\necho bar\n");
+  chmod("foo.sh", 0555);
+  CHECK(hash_multicommand_output(h2, "echo foo; echo bar", "not used"));
+  CHECK(hash_multicommand_output(h1, "./foo.sh", "not used"));
 #else
-       create_file("foo.bat", "@echo off\r\necho foo\r\necho bar\r\n");
-       CHECK(hash_multicommand_output(h2, "echo foo; echo bar", "not used"));
-       CHECK(hash_multicommand_output(h1, "foo.bat", "not used"));
+  create_file("foo.bat", "@echo off\r\necho foo\r\necho bar\r\n");
+  CHECK(hash_multicommand_output(h2, "echo foo; echo bar", "not used"));
+  CHECK(hash_multicommand_output(h1, "foo.bat", "not used"));
 #endif
-       hash_result_as_string(h1, d1);
-       hash_result_as_string(h2, d2);
-       CHECK_STR_EQ(d1, d2);
+  hash_result_as_string(h1, d1);
+  hash_result_as_string(h2, d2);
+  CHECK_STR_EQ(d1, d2);
 
-       hash_free(h2);
-       hash_free(h1);
+  hash_free(h2);
+  hash_free(h1);
 }
 
 TEST(hash_multicommand_output_error_handling)
 {
-       struct hash *h1 = hash_init();
-       struct hash *h2 = hash_init();
+  struct hash* h1 = hash_init();
+  struct hash* h2 = hash_init();
 
-       CHECK(!hash_multicommand_output(h2, "false; true", "not used"));
+  CHECK(!hash_multicommand_output(h2, "false; true", "not used"));
 
-       hash_free(h2);
-       hash_free(h1);
+  hash_free(h2);
+  hash_free(h1);
 }
 
 TEST(check_for_temporal_macros)
 {
-       const char time_start[] =
-               "__TIME__\n"
-               "int a;\n";
-       const char time_middle[] =
-               "#define a __TIME__\n"
-               "int a;\n";
-       const char time_end[] =
-               "#define a __TIME__";
-
-       const char date_start[] =
-               "__DATE__\n"
-               "int ab;\n";
-       const char date_middle[] =
-               "#define ab __DATE__\n"
-               "int ab;\n";
-       const char date_end[] =
-               "#define ab __DATE__";
-
-       const char no_temporal[] =
-               "#define ab a__DATE__\n"
-               "#define ab  __DATE__a\n"
-               "#define ab A__DATE__\n"
-               "#define ab  __DATE__A\n"
-               "#define ab 0__DATE__\n"
-               "#define ab  __DATE__0\n"
-               "#define ab _ _DATE__\n"
-               "#define ab _ _DATE__\n"
-               "#define ab __ DATE__\n"
-               "#define ab __D ATE__\n"
-               "#define ab __DA TE__\n"
-               "#define ab __DAT E__\n"
-               "#define ab __DATE __\n"
-               "#define ab __DATE_ _\n"
-               "#define ab _ _TIME__\n"
-               "#define ab __ TIME__\n"
-               "#define ab __T IME__\n"
-               "#define ab __TI ME__\n"
-               "#define ab __TIM E__\n"
-               "#define ab __TIME __\n"
-               "#define ab __TIME_ _\n";
-
-       CHECK(check_for_temporal_macros(time_start + 0, sizeof(time_start) - 0));
-       CHECK(!check_for_temporal_macros(time_start + 1, sizeof(time_start) - 1));
-
-       CHECK(check_for_temporal_macros(time_middle + 0, sizeof(time_middle) - 0));
-       CHECK(check_for_temporal_macros(time_middle + 1, sizeof(time_middle) - 1));
-       CHECK(check_for_temporal_macros(time_middle + 2, sizeof(time_middle) - 2));
-       CHECK(check_for_temporal_macros(time_middle + 3, sizeof(time_middle) - 3));
-       CHECK(check_for_temporal_macros(time_middle + 4, sizeof(time_middle) - 4));
-       CHECK(check_for_temporal_macros(time_middle + 5, sizeof(time_middle) - 5));
-       CHECK(check_for_temporal_macros(time_middle + 6, sizeof(time_middle) - 6));
-       CHECK(check_for_temporal_macros(time_middle + 7, sizeof(time_middle) - 7));
-
-       CHECK(check_for_temporal_macros(time_end + 0, sizeof(time_end) - 0));
-       CHECK(check_for_temporal_macros(time_end + sizeof(time_end) - 9, 9));
-       CHECK(!check_for_temporal_macros(time_end + sizeof(time_end) - 8, 8));
-
-       CHECK(check_for_temporal_macros(date_start + 0, sizeof(date_start) - 0));
-       CHECK(!check_for_temporal_macros(date_start + 1, sizeof(date_start) - 1));
-
-       CHECK(check_for_temporal_macros(date_middle + 0, sizeof(date_middle) - 0));
-       CHECK(check_for_temporal_macros(date_middle + 1, sizeof(date_middle) - 1));
-       CHECK(check_for_temporal_macros(date_middle + 2, sizeof(date_middle) - 2));
-       CHECK(check_for_temporal_macros(date_middle + 3, sizeof(date_middle) - 3));
-       CHECK(check_for_temporal_macros(date_middle + 4, sizeof(date_middle) - 4));
-       CHECK(check_for_temporal_macros(date_middle + 5, sizeof(date_middle) - 5));
-       CHECK(check_for_temporal_macros(date_middle + 6, sizeof(date_middle) - 6));
-       CHECK(check_for_temporal_macros(date_middle + 7, sizeof(date_middle) - 7));
-
-       CHECK(check_for_temporal_macros(date_end + 0, sizeof(date_end) - 0));
-       CHECK(check_for_temporal_macros(date_end + sizeof(date_end) - 9, 9));
-       CHECK(!check_for_temporal_macros(date_end + sizeof(date_end) - 8, 8));
-
-       CHECK(!check_for_temporal_macros(no_temporal + 0, sizeof(no_temporal) - 0));
-       CHECK(!check_for_temporal_macros(no_temporal + 1, sizeof(no_temporal) - 1));
-       CHECK(!check_for_temporal_macros(no_temporal + 2, sizeof(no_temporal) - 2));
-       CHECK(!check_for_temporal_macros(no_temporal + 3, sizeof(no_temporal) - 3));
-       CHECK(!check_for_temporal_macros(no_temporal + 4, sizeof(no_temporal) - 4));
-       CHECK(!check_for_temporal_macros(no_temporal + 5, sizeof(no_temporal) - 5));
-       CHECK(!check_for_temporal_macros(no_temporal + 6, sizeof(no_temporal) - 6));
-       CHECK(!check_for_temporal_macros(no_temporal + 7, sizeof(no_temporal) - 7));
+  const char time_start[] =
+    "__TIME__\n"
+    "int a;\n";
+  const char time_middle[] =
+    "#define a __TIME__\n"
+    "int a;\n";
+  const char time_end[] = "#define a __TIME__";
+
+  const char date_start[] =
+    "__DATE__\n"
+    "int ab;\n";
+  const char date_middle[] =
+    "#define ab __DATE__\n"
+    "int ab;\n";
+  const char date_end[] = "#define ab __DATE__";
+
+  const char no_temporal[] =
+    "#define ab a__DATE__\n"
+    "#define ab  __DATE__a\n"
+    "#define ab A__DATE__\n"
+    "#define ab  __DATE__A\n"
+    "#define ab 0__DATE__\n"
+    "#define ab  __DATE__0\n"
+    "#define ab _ _DATE__\n"
+    "#define ab _ _DATE__\n"
+    "#define ab __ DATE__\n"
+    "#define ab __D ATE__\n"
+    "#define ab __DA TE__\n"
+    "#define ab __DAT E__\n"
+    "#define ab __DATE __\n"
+    "#define ab __DATE_ _\n"
+    "#define ab _ _TIME__\n"
+    "#define ab __ TIME__\n"
+    "#define ab __T IME__\n"
+    "#define ab __TI ME__\n"
+    "#define ab __TIM E__\n"
+    "#define ab __TIME __\n"
+    "#define ab __TIME_ _\n";
+
+  CHECK(check_for_temporal_macros(time_start + 0, sizeof(time_start) - 0));
+  CHECK(!check_for_temporal_macros(time_start + 1, sizeof(time_start) - 1));
+
+  CHECK(check_for_temporal_macros(time_middle + 0, sizeof(time_middle) - 0));
+  CHECK(check_for_temporal_macros(time_middle + 1, sizeof(time_middle) - 1));
+  CHECK(check_for_temporal_macros(time_middle + 2, sizeof(time_middle) - 2));
+  CHECK(check_for_temporal_macros(time_middle + 3, sizeof(time_middle) - 3));
+  CHECK(check_for_temporal_macros(time_middle + 4, sizeof(time_middle) - 4));
+  CHECK(check_for_temporal_macros(time_middle + 5, sizeof(time_middle) - 5));
+  CHECK(check_for_temporal_macros(time_middle + 6, sizeof(time_middle) - 6));
+  CHECK(check_for_temporal_macros(time_middle + 7, sizeof(time_middle) - 7));
+
+  CHECK(check_for_temporal_macros(time_end + 0, sizeof(time_end) - 0));
+  CHECK(check_for_temporal_macros(time_end + sizeof(time_end) - 9, 9));
+  CHECK(!check_for_temporal_macros(time_end + sizeof(time_end) - 8, 8));
+
+  CHECK(check_for_temporal_macros(date_start + 0, sizeof(date_start) - 0));
+  CHECK(!check_for_temporal_macros(date_start + 1, sizeof(date_start) - 1));
+
+  CHECK(check_for_temporal_macros(date_middle + 0, sizeof(date_middle) - 0));
+  CHECK(check_for_temporal_macros(date_middle + 1, sizeof(date_middle) - 1));
+  CHECK(check_for_temporal_macros(date_middle + 2, sizeof(date_middle) - 2));
+  CHECK(check_for_temporal_macros(date_middle + 3, sizeof(date_middle) - 3));
+  CHECK(check_for_temporal_macros(date_middle + 4, sizeof(date_middle) - 4));
+  CHECK(check_for_temporal_macros(date_middle + 5, sizeof(date_middle) - 5));
+  CHECK(check_for_temporal_macros(date_middle + 6, sizeof(date_middle) - 6));
+  CHECK(check_for_temporal_macros(date_middle + 7, sizeof(date_middle) - 7));
+
+  CHECK(check_for_temporal_macros(date_end + 0, sizeof(date_end) - 0));
+  CHECK(check_for_temporal_macros(date_end + sizeof(date_end) - 9, 9));
+  CHECK(!check_for_temporal_macros(date_end + sizeof(date_end) - 8, 8));
+
+  CHECK(!check_for_temporal_macros(no_temporal + 0, sizeof(no_temporal) - 0));
+  CHECK(!check_for_temporal_macros(no_temporal + 1, sizeof(no_temporal) - 1));
+  CHECK(!check_for_temporal_macros(no_temporal + 2, sizeof(no_temporal) - 2));
+  CHECK(!check_for_temporal_macros(no_temporal + 3, sizeof(no_temporal) - 3));
+  CHECK(!check_for_temporal_macros(no_temporal + 4, sizeof(no_temporal) - 4));
+  CHECK(!check_for_temporal_macros(no_temporal + 5, sizeof(no_temporal) - 5));
+  CHECK(!check_for_temporal_macros(no_temporal + 6, sizeof(no_temporal) - 6));
+  CHECK(!check_for_temporal_macros(no_temporal + 7, sizeof(no_temporal) - 7));
 }
 
 TEST_SUITE_END
index f75adf36aa48ff67441cbb523c4e63c8ea35d187..334b338872a10ef540dc65aefd84f0c0386794c7 100644 (file)
@@ -26,53 +26,53 @@ TEST_SUITE(lockfile)
 
 TEST(acquire_should_create_symlink)
 {
-       lockfile_acquire("test", 1000);
+  lockfile_acquire("test", 1000);
 
 #if defined(_WIN32) || defined(__CYGWIN__)
-       CHECK(path_exists("test.lock"));
+  CHECK(path_exists("test.lock"));
 #else
-       CHECK(is_symlink("test.lock"));
+  CHECK(is_symlink("test.lock"));
 #endif
 }
 
 TEST(release_should_delete_file)
 {
-       create_file("test.lock", "");
-       lockfile_release("test");
+  create_file("test.lock", "");
+  lockfile_release("test");
 
-       CHECK(!path_exists("test.lock"));
+  CHECK(!path_exists("test.lock"));
 }
 
 TEST(lock_breaking)
 {
-       char *p;
+  char* p;
 
 #if defined(_WIN32) || defined(__CYGWIN__)
-       create_file("test.lock", "foo");
-       create_file("test.lock.lock", "foo");
+  create_file("test.lock", "foo");
+  create_file("test.lock.lock", "foo");
 #else
-       CHECK_INT_EQ(0, symlink("foo", "test.lock"));
-       CHECK_INT_EQ(0, symlink("foo", "test.lock.lock"));
+  CHECK_INT_EQ(0, symlink("foo", "test.lock"));
+  CHECK_INT_EQ(0, symlink("foo", "test.lock.lock"));
 #endif
-       CHECK(lockfile_acquire("test", 1000));
+  CHECK(lockfile_acquire("test", 1000));
 
 #if defined(_WIN32) || defined(__CYGWIN__)
-       p = read_text_file("test.lock", 0);
+  p = read_text_file("test.lock", 0);
 #else
-       p = x_readlink("test.lock");
+  p = x_readlink("test.lock");
 #endif
-       CHECK(p);
-       CHECK(!str_eq(p, "foo"));
-       CHECK(!path_exists("test.lock.lock"));
+  CHECK(p);
+  CHECK(!str_eq(p, "foo"));
+  CHECK(!path_exists("test.lock.lock"));
 
-       free(p);
+  free(p);
 }
 
 #if !defined(_WIN32) && !defined(__CYGWIN__)
 TEST(failed_lock_breaking)
 {
-       create_file("test.lock", "");
-       CHECK(!lockfile_acquire("test", 1000));
+  create_file("test.lock", "");
+  CHECK(!lockfile_acquire("test", 1000));
 }
 #endif
 
index 02a2841425de684262647008e787ff9d1c46bbf6..aa3aaa26bda1f7395c16aac857dde2b8c64b0bda 100644 (file)
@@ -27,25 +27,25 @@ TEST_SUITE(stats)
 
 TEST(forward_compatibility)
 {
-       unsigned i;
-       FILE *f;
-       struct counters *counters = counters_init(0);
+  unsigned i;
+  FILE* f;
+  struct counters* counters = counters_init(0);
 
-       f = fopen("stats", "w");
-       for (i = 0; i < 100; i++) {
-               fprintf(f, "%u\n", i);
-       }
-       fclose(f);
+  f = fopen("stats", "w");
+  for (i = 0; i < 100; i++) {
+    fprintf(f, "%u\n", i);
+  }
+  fclose(f);
 
-       stats_read("stats", counters);
-       CHECK_INT_EQ(100, counters->size);
-       CHECK_INT_EQ(73, counters->data[73]);
+  stats_read("stats", counters);
+  CHECK_INT_EQ(100, counters->size);
+  CHECK_INT_EQ(73, counters->data[73]);
 
-       stats_write("stats", counters);
-       CHECK_INT_EQ(100, counters->size);
-       CHECK_INT_EQ(99, counters->data[99]);
+  stats_write("stats", counters);
+  CHECK_INT_EQ(100, counters->size);
+  CHECK_INT_EQ(99, counters->data[99]);
 
-       counters_free(counters);
+  counters_free(counters);
 }
 
 TEST_SUITE_END
index c16c4663dae92b376c42a57cdd7a1aadc77e5e5d..88e6c8c61c37b187398c9c25eded07e901463ad1 100644 (file)
@@ -27,182 +27,180 @@ TEST_SUITE(util)
 
 TEST(x_basename)
 {
-       CHECK_STR_EQ_FREE2("foo.c", x_basename("foo.c"));
-       CHECK_STR_EQ_FREE2("foo.c", x_basename("dir1/dir2/foo.c"));
-       CHECK_STR_EQ_FREE2("foo.c", x_basename("/dir/foo.c"));
-       CHECK_STR_EQ_FREE2("", x_basename("dir1/dir2/"));
+  CHECK_STR_EQ_FREE2("foo.c", x_basename("foo.c"));
+  CHECK_STR_EQ_FREE2("foo.c", x_basename("dir1/dir2/foo.c"));
+  CHECK_STR_EQ_FREE2("foo.c", x_basename("/dir/foo.c"));
+  CHECK_STR_EQ_FREE2("", x_basename("dir1/dir2/"));
 }
 
 TEST(x_dirname)
 {
-       CHECK_STR_EQ_FREE2(".", x_dirname("foo.c"));
-       CHECK_STR_EQ_FREE2(".", x_dirname(""));
-       CHECK_STR_EQ_FREE2("/", x_dirname("/"));
-       CHECK_STR_EQ_FREE2("/", x_dirname("/foo.c"));
-       CHECK_STR_EQ_FREE2("dir1/dir2", x_dirname("dir1/dir2/foo.c"));
-       CHECK_STR_EQ_FREE2("/dir", x_dirname("/dir/foo.c"));
-       CHECK_STR_EQ_FREE2("dir1/dir2", x_dirname("dir1/dir2/"));
+  CHECK_STR_EQ_FREE2(".", x_dirname("foo.c"));
+  CHECK_STR_EQ_FREE2(".", x_dirname(""));
+  CHECK_STR_EQ_FREE2("/", x_dirname("/"));
+  CHECK_STR_EQ_FREE2("/", x_dirname("/foo.c"));
+  CHECK_STR_EQ_FREE2("dir1/dir2", x_dirname("dir1/dir2/foo.c"));
+  CHECK_STR_EQ_FREE2("/dir", x_dirname("/dir/foo.c"));
+  CHECK_STR_EQ_FREE2("dir1/dir2", x_dirname("dir1/dir2/"));
 }
 
 TEST(common_dir_prefix_length)
 {
-       CHECK_INT_EQ(0, common_dir_prefix_length("", ""));
-       CHECK_INT_EQ(0, common_dir_prefix_length("/", "/"));
-       CHECK_INT_EQ(0, common_dir_prefix_length("/", "/b"));
-       CHECK_INT_EQ(0, common_dir_prefix_length("/a", "/b"));
-       CHECK_INT_EQ(2, common_dir_prefix_length("/a", "/a"));
-       CHECK_INT_EQ(2, common_dir_prefix_length("/a", "/a/b"));
-       CHECK_INT_EQ(2, common_dir_prefix_length("/a/b", "/a/c"));
-       CHECK_INT_EQ(4, common_dir_prefix_length("/a/b", "/a/b"));
-       CHECK_INT_EQ(2, common_dir_prefix_length("/a/bc", "/a/b"));
-       CHECK_INT_EQ(2, common_dir_prefix_length("/a/b", "/a/bc"));
+  CHECK_INT_EQ(0, common_dir_prefix_length("", ""));
+  CHECK_INT_EQ(0, common_dir_prefix_length("/", "/"));
+  CHECK_INT_EQ(0, common_dir_prefix_length("/", "/b"));
+  CHECK_INT_EQ(0, common_dir_prefix_length("/a", "/b"));
+  CHECK_INT_EQ(2, common_dir_prefix_length("/a", "/a"));
+  CHECK_INT_EQ(2, common_dir_prefix_length("/a", "/a/b"));
+  CHECK_INT_EQ(2, common_dir_prefix_length("/a/b", "/a/c"));
+  CHECK_INT_EQ(4, common_dir_prefix_length("/a/b", "/a/b"));
+  CHECK_INT_EQ(2, common_dir_prefix_length("/a/bc", "/a/b"));
+  CHECK_INT_EQ(2, common_dir_prefix_length("/a/b", "/a/bc"));
 }
 
 TEST(get_relative_path)
 {
 #ifdef _WIN32
-       CHECK_STR_EQ_FREE2("a", get_relative_path("C:/doesn't matter", "a"));
-       CHECK_STR_EQ_FREE2("a/b", get_relative_path("C:/doesn't matter", "a/b"));
-       CHECK_STR_EQ_FREE2(".", get_relative_path("C:/a", "C:/a"));
-       CHECK_STR_EQ_FREE2("..", get_relative_path("C:/a/b", "C:/a"));
-       CHECK_STR_EQ_FREE2("b", get_relative_path("C:/a", "C:/a/b"));
-       CHECK_STR_EQ_FREE2("b/c", get_relative_path("C:/a", "C:/a/b/c"));
-       CHECK_STR_EQ_FREE2("../c", get_relative_path("C:/a/b", "C:/a/c"));
-       CHECK_STR_EQ_FREE2("../c/d", get_relative_path("C:/a/b", "C:/a/c/d"));
-       CHECK_STR_EQ_FREE2("../../c/d", get_relative_path("C:/a/b/c", "C:/a/c/d"));
-       CHECK_STR_EQ_FREE2("../..", get_relative_path("C:/a/b", "C:/"));
-       CHECK_STR_EQ_FREE2("../../c", get_relative_path("C:/a/b", "C:/c"));
-       CHECK_STR_EQ_FREE2("a/b", get_relative_path("C:/", "C:/a/b"));
+  CHECK_STR_EQ_FREE2("a", get_relative_path("C:/doesn't matter", "a"));
+  CHECK_STR_EQ_FREE2("a/b", get_relative_path("C:/doesn't matter", "a/b"));
+  CHECK_STR_EQ_FREE2(".", get_relative_path("C:/a", "C:/a"));
+  CHECK_STR_EQ_FREE2("..", get_relative_path("C:/a/b", "C:/a"));
+  CHECK_STR_EQ_FREE2("b", get_relative_path("C:/a", "C:/a/b"));
+  CHECK_STR_EQ_FREE2("b/c", get_relative_path("C:/a", "C:/a/b/c"));
+  CHECK_STR_EQ_FREE2("../c", get_relative_path("C:/a/b", "C:/a/c"));
+  CHECK_STR_EQ_FREE2("../c/d", get_relative_path("C:/a/b", "C:/a/c/d"));
+  CHECK_STR_EQ_FREE2("../../c/d", get_relative_path("C:/a/b/c", "C:/a/c/d"));
+  CHECK_STR_EQ_FREE2("../..", get_relative_path("C:/a/b", "C:/"));
+  CHECK_STR_EQ_FREE2("../../c", get_relative_path("C:/a/b", "C:/c"));
+  CHECK_STR_EQ_FREE2("a/b", get_relative_path("C:/", "C:/a/b"));
 #else
-       CHECK_STR_EQ_FREE2("a", get_relative_path("/doesn't matter", "a"));
-       CHECK_STR_EQ_FREE2("a/b", get_relative_path("/doesn't matter", "a/b"));
-       CHECK_STR_EQ_FREE2(".", get_relative_path("/a", "/a"));
-       CHECK_STR_EQ_FREE2("..", get_relative_path("/a/b", "/a"));
-       CHECK_STR_EQ_FREE2("b", get_relative_path("/a", "/a/b"));
-       CHECK_STR_EQ_FREE2("b/c", get_relative_path("/a", "/a/b/c"));
-       CHECK_STR_EQ_FREE2("../c", get_relative_path("/a/b", "/a/c"));
-       CHECK_STR_EQ_FREE2("../c/d", get_relative_path("/a/b", "/a/c/d"));
-       CHECK_STR_EQ_FREE2("../../c/d", get_relative_path("/a/b/c", "/a/c/d"));
-       CHECK_STR_EQ_FREE2("../..", get_relative_path("/a/b", "/"));
-       CHECK_STR_EQ_FREE2("../../c", get_relative_path("/a/b", "/c"));
-       CHECK_STR_EQ_FREE2("a/b", get_relative_path("/", "/a/b"));
+  CHECK_STR_EQ_FREE2("a", get_relative_path("/doesn't matter", "a"));
+  CHECK_STR_EQ_FREE2("a/b", get_relative_path("/doesn't matter", "a/b"));
+  CHECK_STR_EQ_FREE2(".", get_relative_path("/a", "/a"));
+  CHECK_STR_EQ_FREE2("..", get_relative_path("/a/b", "/a"));
+  CHECK_STR_EQ_FREE2("b", get_relative_path("/a", "/a/b"));
+  CHECK_STR_EQ_FREE2("b/c", get_relative_path("/a", "/a/b/c"));
+  CHECK_STR_EQ_FREE2("../c", get_relative_path("/a/b", "/a/c"));
+  CHECK_STR_EQ_FREE2("../c/d", get_relative_path("/a/b", "/a/c/d"));
+  CHECK_STR_EQ_FREE2("../../c/d", get_relative_path("/a/b/c", "/a/c/d"));
+  CHECK_STR_EQ_FREE2("../..", get_relative_path("/a/b", "/"));
+  CHECK_STR_EQ_FREE2("../../c", get_relative_path("/a/b", "/c"));
+  CHECK_STR_EQ_FREE2("a/b", get_relative_path("/", "/a/b"));
 #endif
 }
 
 TEST(subst_env_in_string)
 {
-       char *errmsg;
+  char* errmsg;
 
-       putenv(FOO_ENV);
+  putenv(FOO_ENV);
 
-       CHECK_STR_EQ_FREE2("bar",
-                          subst_env_in_string("$FOO", &errmsg));
-       CHECK(!errmsg);
+  CHECK_STR_EQ_FREE2("bar", subst_env_in_string("$FOO", &errmsg));
+  CHECK(!errmsg);
 
-       CHECK_STR_EQ_FREE2("$",
-                          subst_env_in_string("$", &errmsg));
-       CHECK(!errmsg);
+  CHECK_STR_EQ_FREE2("$", subst_env_in_string("$", &errmsg));
+  CHECK(!errmsg);
 
-       CHECK_STR_EQ_FREE2("bar bar:bar",
-                          subst_env_in_string("$FOO $FOO:$FOO", &errmsg));
-       CHECK(!errmsg);
+  CHECK_STR_EQ_FREE2("bar bar:bar",
+                     subst_env_in_string("$FOO $FOO:$FOO", &errmsg));
+  CHECK(!errmsg);
 
-       CHECK_STR_EQ_FREE2("xbar",
-                          subst_env_in_string("x$FOO", &errmsg));
-       CHECK(!errmsg);
+  CHECK_STR_EQ_FREE2("xbar", subst_env_in_string("x$FOO", &errmsg));
+  CHECK(!errmsg);
 
-       CHECK_STR_EQ_FREE2("barx",
-                          subst_env_in_string("${FOO}x", &errmsg));
-       CHECK(!errmsg);
+  CHECK_STR_EQ_FREE2("barx", subst_env_in_string("${FOO}x", &errmsg));
+  CHECK(!errmsg);
 
-       CHECK(!subst_env_in_string("$surelydoesntexist", &errmsg));
-       CHECK_STR_EQ_FREE2("environment variable \"surelydoesntexist\" not set",
-                          errmsg);
+  CHECK(!subst_env_in_string("$surelydoesntexist", &errmsg));
+  CHECK_STR_EQ_FREE2("environment variable \"surelydoesntexist\" not set",
+                     errmsg);
 
-       CHECK(!subst_env_in_string("${FOO", &errmsg));
-       CHECK_STR_EQ_FREE2("syntax error: missing '}' after \"FOO\"", errmsg);
+  CHECK(!subst_env_in_string("${FOO", &errmsg));
+  CHECK_STR_EQ_FREE2("syntax error: missing '}' after \"FOO\"", errmsg);
 }
 
 TEST(format_human_readable_size)
 {
-       CHECK_STR_EQ_FREE2("0.0 MB", format_human_readable_size(0));
-       CHECK_STR_EQ_FREE2("0.0 MB", format_human_readable_size(49));
-       CHECK_STR_EQ_FREE2("0.4 MB", format_human_readable_size(420 * 1000));
-       CHECK_STR_EQ_FREE2("1.0 MB", format_human_readable_size(1000 * 1000));
-       CHECK_STR_EQ_FREE2("1.2 MB", format_human_readable_size(1234 * 1000));
-       CHECK_STR_EQ_FREE2("438.5 MB",
-                          format_human_readable_size(438.5 * 1000 * 1000));
-       CHECK_STR_EQ_FREE2("1.0 GB",
-                          format_human_readable_size(1000 * 1000 * 1000));
-       CHECK_STR_EQ_FREE2("17.1 GB",
-                          format_human_readable_size(17.11 * 1000 * 1000 * 1000));
+  CHECK_STR_EQ_FREE2("0.0 MB", format_human_readable_size(0));
+  CHECK_STR_EQ_FREE2("0.0 MB", format_human_readable_size(49));
+  CHECK_STR_EQ_FREE2("0.4 MB", format_human_readable_size(420 * 1000));
+  CHECK_STR_EQ_FREE2("1.0 MB", format_human_readable_size(1000 * 1000));
+  CHECK_STR_EQ_FREE2("1.2 MB", format_human_readable_size(1234 * 1000));
+  CHECK_STR_EQ_FREE2("438.5 MB",
+                     format_human_readable_size(438.5 * 1000 * 1000));
+  CHECK_STR_EQ_FREE2("1.0 GB", format_human_readable_size(1000 * 1000 * 1000));
+  CHECK_STR_EQ_FREE2("17.1 GB",
+                     format_human_readable_size(17.11 * 1000 * 1000 * 1000));
 }
 
 TEST(format_parsable_size_with_suffix)
 {
-       CHECK_STR_EQ_FREE2("0", format_parsable_size_with_suffix(0));
-       CHECK_STR_EQ_FREE2("42000", format_parsable_size_with_suffix(42 * 1000));
-       CHECK_STR_EQ_FREE2("1.0M", format_parsable_size_with_suffix(1000 * 1000));
-       CHECK_STR_EQ_FREE2("1.2M", format_parsable_size_with_suffix(1234 * 1000));
-       CHECK_STR_EQ_FREE2("438.5M",
-                          format_parsable_size_with_suffix(438.5 * 1000 * 1000));
-       CHECK_STR_EQ_FREE2("1.0G",
-                          format_parsable_size_with_suffix(1000 * 1000 * 1000));
-       CHECK_STR_EQ_FREE2(
-               "17.1G",
-               format_parsable_size_with_suffix(17.11 * 1000 * 1000 * 1000));
+  CHECK_STR_EQ_FREE2("0", format_parsable_size_with_suffix(0));
+  CHECK_STR_EQ_FREE2("42000", format_parsable_size_with_suffix(42 * 1000));
+  CHECK_STR_EQ_FREE2("1.0M", format_parsable_size_with_suffix(1000 * 1000));
+  CHECK_STR_EQ_FREE2("1.2M", format_parsable_size_with_suffix(1234 * 1000));
+  CHECK_STR_EQ_FREE2("438.5M",
+                     format_parsable_size_with_suffix(438.5 * 1000 * 1000));
+  CHECK_STR_EQ_FREE2("1.0G",
+                     format_parsable_size_with_suffix(1000 * 1000 * 1000));
+  CHECK_STR_EQ_FREE2(
+    "17.1G", format_parsable_size_with_suffix(17.11 * 1000 * 1000 * 1000));
 }
 
 TEST(parse_size_with_suffix)
 {
-       uint64_t size;
-       size_t i;
-       struct { const char *size; int64_t expected; } sizes[] = {
-               {"0", 0},
-               {"42", (int64_t)42 * 1000 * 1000 * 1000}, // Default suffix: G
-
-               {"78k",       78 * 1000},
-               {"78K",       78 * 1000},
-               {"1.1 M",     (int64_t)(1.1 * 1000 * 1000)},
-               {"438.55M",   (int64_t)(438.55 * 1000 * 1000)},
-               {"1 G",       1 * 1000 * 1000 * 1000},
-               {"2T",        (int64_t)2 * 1000 * 1000 * 1000 * 1000},
-
-               {"78 Ki",     78 * 1024},
-               {"1.1Mi",     (int64_t)(1.1 * 1024 * 1024)},
-               {"438.55 Mi", (int64_t)(438.55 * 1024 * 1024)},
-               {"1Gi",       1 * 1024 * 1024 * 1024},
-               {"2 Ti",      (int64_t)2 * 1024 * 1024 * 1024 * 1024},
-       };
-
-       for (i = 0; i < ARRAY_SIZE(sizes); ++i) {
-               CHECKM(parse_size_with_suffix(sizes[i].size, &size), sizes[i].size);
-               CHECK_INT_EQ(sizes[i].expected, size);
-       }
+  uint64_t size;
+  size_t i;
+  struct
+  {
+    const char* size;
+    int64_t expected;
+  } sizes[] = {
+    {"0", 0},
+    {"42", (int64_t)42 * 1000 * 1000 * 1000}, // Default suffix: G
+
+    {"78k", 78 * 1000},
+    {"78K", 78 * 1000},
+    {"1.1 M", (int64_t)(1.1 * 1000 * 1000)},
+    {"438.55M", (int64_t)(438.55 * 1000 * 1000)},
+    {"1 G", 1 * 1000 * 1000 * 1000},
+    {"2T", (int64_t)2 * 1000 * 1000 * 1000 * 1000},
+
+    {"78 Ki", 78 * 1024},
+    {"1.1Mi", (int64_t)(1.1 * 1024 * 1024)},
+    {"438.55 Mi", (int64_t)(438.55 * 1024 * 1024)},
+    {"1Gi", 1 * 1024 * 1024 * 1024},
+    {"2 Ti", (int64_t)2 * 1024 * 1024 * 1024 * 1024},
+  };
+
+  for (i = 0; i < ARRAY_SIZE(sizes); ++i) {
+    CHECKM(parse_size_with_suffix(sizes[i].size, &size), sizes[i].size);
+    CHECK_INT_EQ(sizes[i].expected, size);
+  }
 }
 
 TEST(format_command)
 {
-       const char *argv[] = {"foo", "bar", NULL};
+  const char* argv[] = {"foo", "bar", NULL};
 
-       CHECK_STR_EQ_FREE2("foo bar\n", format_command(argv));
+  CHECK_STR_EQ_FREE2("foo bar\n", format_command(argv));
 }
 
 TEST(format_hex)
 {
-       uint8_t none[] = "";
-       uint8_t text[4] = "foo"; // incl. NUL
-       uint8_t data[4] = {0, 1, 2, 3};
-       char result[2 * sizeof(data) + 1] = ".";
+  uint8_t none[] = "";
+  uint8_t text[4] = "foo"; // incl. NUL
+  uint8_t data[4] = {0, 1, 2, 3};
+  char result[2 * sizeof(data) + 1] = ".";
 
-       format_hex(none, 0, result);
-       CHECK_STR_EQ("", result);
+  format_hex(none, 0, result);
+  CHECK_STR_EQ("", result);
 
-       format_hex(text, sizeof(text), result);
-       CHECK_STR_EQ("666f6f00", result);
+  format_hex(text, sizeof(text), result);
+  CHECK_STR_EQ("666f6f00", result);
 
-       format_hex(data, sizeof(data), result);
-       CHECK_STR_EQ("00010203", result);
+  format_hex(data, sizeof(data), result);
+  CHECK_STR_EQ("00010203", result);
 }
 
 TEST_SUITE_END
index af4515861a1589c24a806c02b52a05718d12396b..0a5009fd4ef2f605d45b2bace665c28852aec550 100644 (file)
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "../src/system.hpp"
 #include "util.hpp"
 
+#include "../src/system.hpp"
+
 #ifdef _WIN32
-#    define lstat(a, b) stat(a, b)
+#  define lstat(a, b) stat(a, b)
 #endif
 
 bool
-path_exists(const char *path)
+path_exists(const charpath)
 {
-       struct stat st;
-       return lstat(path, &st) == 0;
+  struct stat st;
+  return lstat(path, &st) == 0;
 }
 
 void
-create_file(const char *path, const char *content)
+create_file(const char* path, const char* content)
 {
-       FILE *f = fopen(path, "w");
-       if (!f || fputs(content, f) < 0) {
-               fprintf(stderr, "create_file: %s: %s\n", path, strerror(errno));
-       }
-       if (f) {
-               fclose(f);
-       }
+  FILE* f = fopen(path, "w");
+  if (!f || fputs(content, f) < 0) {
+    fprintf(stderr, "create_file: %s: %s\n", path, strerror(errno));
+  }
+  if (f) {
+    fclose(f);
+  }
 }
index 275b7c425304fb70be3779fe223552fcbdbcd1e7..294483e35c53db3a5fec2c4baf6cf4c5c01b8fbe 100644 (file)
@@ -20,6 +20,6 @@
 
 #include <stdbool.h>
 
-bool path_exists(const char *path);
-bool is_symlink(const char *path);
-void create_file(const char *path, const char *content);
+bool path_exists(const charpath);
+bool is_symlink(const charpath);
+void create_file(const char* path, const char* content);