<body class="article">\r
<div id="header">\r
<h1>ccache authors</h1>\r
-<span id="revnumber">version 3.2.2</span>\r
+<span id="revnumber">version 3.2.3</span>\r
<div id="toc">
<div id="toctitle">Table of Contents</div>
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</li>\r
<li>\r
<p>\r
-Chiaki ISHIKAWA <<a href="mailto:ishikawa@yk.rim.or.jp">ishikawa@yk.rim.or.jp</a>>\r
+Chiaki Ishikawa <<a href="mailto:ishikawa@yk.rim.or.jp">ishikawa@yk.rim.or.jp</a>>\r
</p>\r
</li>\r
<li>\r
</li>\r
<li>\r
<p>\r
+Michael Marineau <<a href="mailto:michael.marineau@coreos.com">michael.marineau@coreos.com</a>>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
Michael Meeks <<a href="mailto:michael.meeks@suse.com">michael.meeks@suse.com</a>>\r
</p>\r
</li>\r
</li>\r
<li>\r
<p>\r
-Ryb <<a href="mailto:ryb@ableton.com">ryb@ableton.com</a>>\r
+Ryan Brown <<a href="mailto:ryb@ableton.com">ryb@ableton.com</a>>\r
</p>\r
</li>\r
<li>\r
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.2.2<br />\r
+Version 3.2.3<br />\r
Last updated\r
- 2015-05-10 14:23:01 CEST\r
+ 2015-08-16 14:11:14 CEST\r
</div>\r
</div>\r
</body>\r
* Bernhard Bauer <bauerb@chromium.org>
* Björn Jacke <bj@sernet.de>
* Bo Rydberg <bolry@hotmail.com>
-* Chiaki ISHIKAWA <ishikawa@yk.rim.or.jp>
+* Chiaki Ishikawa <ishikawa@yk.rim.or.jp>
* Chris AtLee <chris@atlee.ca>
* Clemens Rabe <crabe@gmx.de>
* David Givone <david@givone.net>
* Luboš Luňák <l.lunak@suse.cz>
* Mark Starovoytov <starovoytov.mark@googlemail.com>
* Martin Pool <mbp@sourcefrog.net>
+* Michael Marineau <michael.marineau@coreos.com>
* Michael Meeks <michael.meeks@suse.com>
* Mike Frysinger <vapier@gentoo.org>
* Orgad Shaneh <orgad.shaneh@audiocodes.com>
* RW <fbsd06@mlists.homeunix.com>
* Ramiro Polla <ramiro.polla@gmail.com>
* Robin H. Johnson <robbat2@gentoo.org>
-* Ryb <ryb@ableton.com>
+* Ryan Brown <ryb@ableton.com>
* Tim Potter <tpot@samba.org>
* Tor Arne Vestbø <torarnv@gmail.com>
* Ville Skyttä <ville.skytta@iki.fi>
Code formatting
---------------
-* Use tabs for indenting and spaces for aligning C code. See
- <http://www.emacswiki.org/emacs/SmartTabs>.
+* Use tabs for indenting and spaces for aligning C code.
* Use 4 spaces for indenting other code (and spaces for aligning).
* Put the opening curly brace on a new line when defining a function, otherwise
at the end of the same line.
* Use only uppercase names for enum items and (with some exceptions) macros.
* Don't use typedefs for structs and enums.
+Tip: Install the tool uncrustify <http://uncrustify.sourceforge.net> and then
+run "make uncrustify" to fix up source code formatting.
+
Idioms
------
<body class="article">\r
<div id="header">\r
<h1>ccache installation</h1>\r
-<span id="revnumber">version 3.2.2</span>\r
+<span id="revnumber">version 3.2.3</span>\r
<div id="toc">
<div id="toctitle">Table of Contents</div>
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
<div class="ulist"><ul>\r
<li>\r
<p>\r
-Perl (<a href="http://www.perl.org/">http://www.perl.org/</a>)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
Python (<a href="http://www.python.org/">http://www.python.org/</a>)\r
</p>\r
</li>\r
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.2.2<br />\r
+Version 3.2.3<br />\r
Last updated\r
- 2015-03-09 20:26:56 CET\r
+ 2015-06-28 18:38:00 CEST\r
</div>\r
</div>\r
</body>\r
To debug and run the performance test suite you'll also need:
-- Perl (http://www.perl.org/)
- Python (http://www.python.org/)
Run "./autogen.sh" and then follow the steps mentioned under "Installation"
<body class="article">\r
<div id="header">\r
<h1>ccache copyright and license</h1>\r
-<span id="revnumber">version 3.2.2</span>\r
+<span id="revnumber">version 3.2.3</span>\r
<div id="toc">
<div id="toctitle">Table of Contents</div>
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.2.2<br />\r
+Version 3.2.3<br />\r
Last updated\r
- 2015-04-19 13:27:37 CEST\r
+ 2015-06-03 20:41:29 CEST\r
</div>\r
</div>\r
</body>\r
<body class="article">\r
<div id="header">\r
<h1>CCACHE(1)</h1>\r
-<span id="revnumber">version 3.2.2</span>\r
+<span id="revnumber">version 3.2.3</span>\r
<div id="toc">
<div id="toctitle">Table of Contents</div>
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.2.2<br />\r
+Version 3.2.3<br />\r
Last updated\r
- 2015-04-19 13:27:37 CEST\r
+ 2015-06-03 20:41:29 CEST\r
</div>\r
</div>\r
</body>\r
<body class="article">\r
<div id="header">\r
<h1>ccache news</h1>\r
-<span id="revnumber">version 3.2.2</span>\r
+<span id="revnumber">version 3.2.3</span>\r
<div id="toc">
<div id="toctitle">Table of Contents</div>
<noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
</div>\r
<div id="content">\r
<div class="sect1">\r
+<h2 id="_ccache_3_2_3">ccache 3.2.3</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Release date: 2015-08-16</p></div>\r
+<div class="sect2">\r
+<h3 id="_new_features_and_improvements">New features and improvements</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Added support for compiler option <code>-gsplit-dwarf</code>.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_bug_fixes">Bug fixes</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Support external zlib in nonstandard directory.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Avoid calling <code>exit()</code> inside an exit handler.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Let exit handler terminate properly.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Bail out on compiler option <code>--save-temps</code> in addition to <code>-save-temps</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Only log "Disabling direct mode" once when failing to read potential include\r
+ files.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
<h2 id="_ccache_3_2_2">ccache 3.2.2</h2>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2015-05-10</p></div>\r
<div class="sect2">\r
-<h3 id="_new_features_and_improvements">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_2">New features and improvements</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes">Bug fixes</h3>\r
+<h3 id="_bug_fixes_2">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
-Fixed bug which could result in false cache hits when source code contains\r
- <code>'"'</code> followed by <code>" /*"</code> or <code>" //"</code> (with variations).\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
Made hash of cached result created with and without <code>CCACHE_CPP2</code> different.\r
This makes it possible to rebuild with <code>CCACHE_CPP2</code> set without having to\r
clear the cache to get new results.\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2014-12-10</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_2">Bug fixes</h3>\r
+<h3 id="_bug_fixes_3">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2014-11-17</p></div>\r
<div class="sect2">\r
-<h3 id="_new_features_and_improvements_2">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_3">New features and improvements</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_3">Bug fixes</h3>\r
+<h3 id="_bug_fixes_4">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2015-03-07</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_4">Bug fixes</h3>\r
+<h3 id="_bug_fixes_5">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2014-10-19</p></div>\r
<div class="sect2">\r
-<h3 id="_new_features_and_improvements_3">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_4">New features and improvements</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_5">Bug fixes</h3>\r
+<h3 id="_bug_fixes_6">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2013-01-06</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_6">Bug fixes</h3>\r
+<h3 id="_bug_fixes_7">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2012-08-11</p></div>\r
<div class="sect2">\r
-<h3 id="_new_features_and_improvements_4">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_5">New features and improvements</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_7">Bug fixes</h3>\r
+<h3 id="_bug_fixes_8">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2012-01-08</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_8">Bug fixes</h3>\r
+<h3 id="_bug_fixes_9">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2011-08-21</p></div>\r
<div class="sect2">\r
-<h3 id="_new_features_and_improvements_5">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_6">New features and improvements</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_9">Bug fixes</h3>\r
+<h3 id="_bug_fixes_10">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2011-05-29</p></div>\r
<div class="sect2">\r
-<h3 id="_new_features_and_improvements_6">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_7">New features and improvements</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_10">Bug fixes</h3>\r
+<h3 id="_bug_fixes_11">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2011-01-09</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_11">Bug fixes</h3>\r
+<h3 id="_bug_fixes_12">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-11-28</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_12">Bug fixes</h3>\r
+<h3 id="_bug_fixes_13">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-11-21</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_13">Bug fixes</h3>\r
+<h3 id="_bug_fixes_14">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-11-07</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_14">Bug fixes</h3>\r
+<h3 id="_bug_fixes_15">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-09-16</p></div>\r
<div class="sect2">\r
-<h3 id="_new_features_and_improvements_7">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_8">New features and improvements</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_15">Bug fixes</h3>\r
+<h3 id="_bug_fixes_16">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-07-15</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_16">Bug fixes</h3>\r
+<h3 id="_bug_fixes_17">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_new_features_and_improvements_8">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_9">New features and improvements</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_17">Bug fixes</h3>\r
+<h3 id="_bug_fixes_18">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.2.2<br />\r
+Version 3.2.3<br />\r
Last updated\r
- 2015-05-10 14:17:58 CEST\r
+ 2015-08-16 14:00:42 CEST\r
</div>\r
</div>\r
</body>\r
===========
+ccache 3.2.3
+------------
+Release date: 2015-08-16
+
+
+New features and improvements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Added support for compiler option `-gsplit-dwarf`.
+
+
+Bug fixes
+~~~~~~~~~
+
+- Support external zlib in nonstandard directory.
+
+- Avoid calling `exit()` inside an exit handler.
+
+- Let exit handler terminate properly.
+
+- Bail out on compiler option `--save-temps` in addition to `-save-temps`.
+
+- Only log "Disabling direct mode" once when failing to read potential include
+ files.
+
+
ccache 3.2.2
------------
Release date: 2015-05-10
Bug fixes
~~~~~~~~~
-- Fixed bug which could result in false cache hits when source code contains
- `'"'` followed by `" /*"` or `" //"` (with variations).
-
- Made hash of cached result created with and without `CCACHE_CPP2` different.
This makes it possible to rebuild with `CCACHE_CPP2` set without having to
clear the cache to get new results.
char *pos, *argtext, *argpos, *argbuf;
char quoting;
- /* Used to track quoting state; if \0, we're not
- * inside quotes. Otherwise stores the quoting character
- * that started it, for matching the end quote */
+ /* Used to track quoting state; if \0, we are not inside quotes. Otherwise
+ * stores the quoting character that started it, for matching the end
+ * quote */
quoting = '\0';
if (!(argtext = read_text_file(filename, 0)))
if (quoting) {
break;
}
- /* Fall through */
+ /* Fall through */
case '\0':
/* end of token */
}
dest->argv = (char **)x_realloc(
- dest->argv,
- (src->argc + dest->argc + 1 - offset) *
- sizeof(char *));
+ dest->argv,
+ (src->argc + dest->argc + 1 - offset) *
+ sizeof(char *));
/* Shift arguments over */
for (i = dest->argc; i >= index + offset; i--) {
.\" Title: ccache
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 05/10/2015
+.\" Date: 08/16/2015
.\" Manual: ccache Manual
-.\" Source: ccache 3.2.2
+.\" Source: ccache 3.2.3
.\" Language: English
.\"
-.TH "CCACHE" "1" "05/10/2015" "ccache 3\&.2\&.2" "ccache Manual"
+.TH "CCACHE" "1" "08/16/2015" "ccache 3\&.2\&.3" "ccache Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
#define TO_STRING(x) STRINGIFY(x)
static const char VERSION_TEXT[] =
-MYNAME " version %s\n"
-"\n"
-"Copyright (C) 2002-2007 Andrew Tridgell\n"
-"Copyright (C) 2009-2015 Joel Rosdahl\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";
+ MYNAME " version %s\n"
+ "\n"
+ "Copyright (C) 2002-2007 Andrew Tridgell\n"
+ "Copyright (C) 2009-2015 Joel Rosdahl\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"
-"Options:\n"
-" -c, --cleanup delete old files and recalculate size counters\n"
-" (normally not needed as this is done 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 for\n"
-" 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) and\n"
-" Ki, Mi, Gi, Ti (binary); default suffix: G\n"
-" -o, --set-config=K=V set configuration key K to value V\n"
-" -p, --print-config print current configuration options\n"
-" -s, --show-stats show statistics summary\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"
-"See also <http://ccache.samba.org>.\n";
+ "Usage:\n"
+ " " MYNAME " [options]\n"
+ " " MYNAME " compiler [compiler options]\n"
+ " compiler [compiler options] (via symbolic link)\n"
+ "\n"
+ "Options:\n"
+ " -c, --cleanup delete old files and recalculate size counters\n"
+ " (normally not needed as this is done 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 for\n"
+ " 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) and\n"
+ " Ki, Mi, Gi, Ti (binary); default suffix: G\n"
+ " -o, --set-config=K=V set configuration key K to value V\n"
+ " -p, --print-config print current configuration options\n"
+ " -s, --show-stats show statistics summary\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"
+ "See also <http://ccache.samba.org>.\n";
/* Global configuration data. */
struct conf *conf = NULL;
/* The path to the coverage file (implicit when using -ftest-coverage). */
static char *output_cov;
-/* Diagnostic generation information (clang). */
+/* Diagnostic generation information (clang). Contains pathname if not
+ * NULL. */
static char *output_dia = NULL;
+/* -gsplit-dwarf support: Split dwarf information (GCC 4.8 and
+ * up). Contains pathname if not NULL. */
+static char *output_dwo = NULL;
+
/*
* Name (represented as a struct file_hash) of the file containing the cached
* object code.
static char *cached_dia;
/*
+ * -gsplit-dwarf support:
+ * Full path to the file containing the split dwarf (for GCC 4.8 and
+ * above)
+ * (cachedir/a/b/cdef[...]-size.dwo).
+ *
+ * contains NULL if -gsplit-dwarf is not given.
+ */
+static char *cached_dwo;
+
+/*
+ * -gsplit-dwarf support:
+ * using_split_dwarf is true if "-gsplit-dwarf" is given to the
+ * compiler (GCC 4.8 and up).
+ */
+bool using_split_dwarf = false;
+
+/*
* Full path to the file containing the manifest
* (cachedir/a/b/cdef[...]-size.manifest).
*/
{
(void)signo;
clean_up_pending_tmp_files();
+ _exit(1);
}
static void
return;
failure:
- cc_log("Disabling direct mode");
- conf->direct_mode = false;
+ if (conf->direct_mode) {
+ cc_log("Disabling direct mode");
+ conf->direct_mode = false;
+ }
/* Fall through. */
ignore:
free(path);
end = data + size;
p = data;
q = data;
- while (q < end - 7) { /* There must be at least 7 characters (# 1 "x") left
- to potentially find an include file path. */
+ /* 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):
* preprocessing as well, for instance "# pragma".
*/
if (q[0] == '#'
- /* GCC: */
+ /* GCC: */
&& ((q[1] == ' ' && q[2] >= '0' && q[2] <= '9')
/* GCC precompiled header: */
|| (q[1] == 'p'
to_cache(struct args *args)
{
char *tmp_stdout, *tmp_stderr, *tmp_aux, *tmp_cov;
+ char *tmp_dwo = NULL;
struct stat st;
int status, tmp_stdout_fd, tmp_stderr_fd;
FILE *f;
tmp_cov = NULL;
}
+ /* GCC (at least 4.8 and 4.9) forms the .dwo file name by removing everything
+ * after (and including) the last "." from the object file name and then
+ * appending ".dwo".
+ */
+ if (using_split_dwarf) {
+ char *base_name = remove_extension(output_obj);
+ tmp_dwo = format("%s.dwo", base_name);
+ free(base_name);
+ }
+
args_add(args, "-o");
args_add(args, output_obj);
if (tmp_cov) {
tmp_unlink(tmp_cov);
}
+ tmp_unlink(tmp_dwo);
failed();
}
if (st.st_size != 0) {
if (tmp_cov) {
tmp_unlink(tmp_cov);
}
+ tmp_unlink(tmp_dwo);
failed();
}
tmp_unlink(tmp_stdout);
close(fd);
tmp_unlink(tmp_stderr);
- exit(status);
+ x_exit(status);
}
tmp_unlink(tmp_stderr);
if (tmp_cov) {
tmp_unlink(tmp_cov);
}
+ tmp_unlink(tmp_dwo);
+
failed();
}
- if (x_stat(output_obj, &st) != 0) {
+ if (stat(output_obj, &st) != 0) {
cc_log("Compiler didn't produce an object file");
stats_update(STATS_NOOUTPUT);
failed();
failed();
}
+ if (using_split_dwarf) {
+ if (stat(tmp_dwo, &st) != 0) {
+ cc_log("Compiler didn't produce a split dwarf file");
+ stats_update(STATS_NOOUTPUT);
+ failed();
+ }
+ if (st.st_size == 0) {
+ cc_log("Compiler produced an empty split dwarf file");
+ stats_update(STATS_EMPTYOUTPUT);
+ failed();
+ }
+ }
+
if (x_stat(tmp_stderr, &st) != 0) {
stats_update(STATS_ERROR);
failed();
}
if (st.st_size > 0) {
if (move_uncompressed_file(
- tmp_stderr, cached_stderr,
- conf->compression ? conf->compression_level : 0) != 0) {
+ tmp_stderr, cached_stderr,
+ conf->compression ? conf->compression_level : 0) != 0) {
cc_log("Failed to move %s to %s: %s", tmp_stderr, cached_stderr,
strerror(errno));
stats_update(STATS_ERROR);
}
put_file_in_cache(output_obj, cached_obj);
+
+ if (using_split_dwarf) {
+ assert(tmp_dwo);
+ assert(cached_dwo);
+ put_file_in_cache(tmp_dwo, cached_dwo);
+ }
+
if (generating_dependencies) {
put_file_in_cache(output_dep, cached_dep);
}
free(tmp_stderr);
free(tmp_stdout);
free(tmp_cov);
+ free(tmp_dwo);
}
/*
struct file_hash *result;
/* ~/hello.c -> tmp.hello.123.i
- limit the basename to 10
- characters in order to cope with filesystem with small
- maximum filename length limits */
+ * limit the basename to 10
+ * characters in order to cope with filesystem with small
+ * maximum filename length limits */
input_base = basename(input_file);
tmp = strchr(input_base, '.');
if (tmp) {
cached_dep = get_path_in_cache(object_name, ".d");
cached_cov = get_path_in_cache(object_name, ".gcno");
cached_dia = get_path_in_cache(object_name, ".dia");
+
+ if (using_split_dwarf) {
+ cached_dwo = get_path_in_cache(object_name, ".dwo");
+ } else {
+ cached_dwo = NULL;
+ }
+
stats_file = format("%s/%c/stats", conf->cache_dir, object_name[0]);
free(object_name);
}
hash_file(hash, path);
} else { /* command string */
if (!hash_multicommand_output(
- hash, conf->compiler_check, orig_args->argv[0])) {
+ hash, conf->compiler_check, orig_args->argv[0])) {
fatal("Failure running compiler check command: %s", conf->compiler_check);
}
}
}
/* The -fdebug-prefix-map option may be used in combination with
- CCACHE_BASEDIR to reuse results across different directories. Skip it
- from hashing. */
+ * CCACHE_BASEDIR to reuse results across different directories. Skip it
+ * from hashing. */
if (str_startswith(args->argv[i], "-fdebug-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. */
+ * 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 (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. */
+ * but don't include the path to it in the hash. */
hash_delimiter(hash, "specs");
hash_compiler(hash, &st, p, false);
continue;
hash_delimiter(hash, "-fprofile-dir");
hash_string(hash, profile_dir);
}
+
if (profile_use) {
/* Calculate gcda name */
char *gcda_name;
return;
}
- /* Check if the object file is there. */
if (stat(cached_obj, &st) != 0) {
cc_log("Object file %s not in cache", cached_obj);
return;
return;
}
+ if (using_split_dwarf && !generating_dependencies) {
+ assert(output_dwo);
+ }
+ if (output_dwo) {
+ assert(cached_dwo);
+ if (stat(cached_dwo, &st) != 0) {
+ cc_log("Split dwarf file %s not in cache", cached_dwo);
+ return;
+ }
+ if (st.st_size == 0) {
+ cc_log("Invalid (empty) dwo file %s in cache", cached_dwo);
+ x_unlink(cached_dwo);
+ x_unlink(cached_obj); /* to really invalidate */
+ return;
+ }
+ }
+
/*
* (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by
* gcc.)
return;
}
+ /*
+ * Copy object file from cache. Do so also for FissionDwarf file, cached_dwo,
+ * when -gsplit-dwarf is specified.
+ */
if (!str_eq(output_obj, "/dev/null")) {
get_file_from_cache(cached_obj, output_obj);
+ if (using_split_dwarf) {
+ assert(output_dwo);
+ get_file_from_cache(cached_dwo, output_dwo);
+ }
}
if (produce_dep_file) {
get_file_from_cache(cached_dep, output_dep);
}
/* Update modification timestamps to save files from LRU cleanup.
- Also gives files a sensible mtime when hard-linking. */
+ * Also gives files a sensible mtime when hard-linking. */
update_mtime(cached_obj);
update_mtime(cached_stderr);
if (produce_dep_file) {
if (output_dia) {
update_mtime(cached_dia);
}
+ if (cached_dwo) {
+ update_mtime(cached_dwo);
+ }
if (generating_dependencies && mode == FROMCACHE_CPP_MODE) {
put_file_in_cache(output_dep, cached_dep);
}
- send_cached_stderr();
+ send_cached_stderr();
if (put_object_in_manifest) {
update_manifest_file();
}
/* and exit with the right status code */
- exit(0);
+ x_exit(0);
}
/* find the real compiler. We just search the PATH to find a executable of the
- same name that isn't a link to ourselves */
+ * same name that isn't a link to ourselves */
static void
find_compiler(char **argv)
{
continue;
}
- /* debugging is handled specially, so that we know if we
- can strip line number info
- */
+ if (str_eq(argv[i], "-gsplit-dwarf")) {
+ cc_log("Enabling caching of dwarf files since -gsplit-dwarf is used");
+ using_split_dwarf = true;
+ args_add(stripped_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(stripped_args, argv[i]);
if (conf->unify && !str_eq(argv[i], "-g0")) {
}
/* These options require special handling, because they
- behave differently with gcc -E, when the output
- file is not specified. */
+ * 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]);
}
/* 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 */
+ * an option, not an input file. This allows us to
+ * cope better with unusual compiler options */
if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
cc_log("%s is not a regular file, not considering as input file",
argv[i]);
/* Rewrite to relative to increase hit rate. */
input_file = make_relative_path(x_strdup(argv[i]));
+ } /* for */
+
+ if (found_S_opt) {
+ /* Even if -gsplit-dwarf is given, the .dwo file is not generated when -S
+ * is also given.
+ */
+ using_split_dwarf = false;
+ cc_log("Disabling caching of dwarf files since -S is used");
}
if (!input_file) {
}
output_is_precompiled_header =
- actual_language && strstr(actual_language, "-header");
+ actual_language && strstr(actual_language, "-header");
if (output_is_precompiled_header
&& !(conf->sloppiness & SLOPPY_PCH_DEFINES)) {
} 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 */
+ * as they are the dominant form of "called for link" in many cases */
if (strstr(input_file, "conftest.")) {
stats_update(STATS_CONFTEST);
} else {
}
}
+ if (using_split_dwarf) {
+ char *p;
+ 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 */
- if (!str_eq(output_obj,"/dev/null")
+ 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);
args_free(orig_args); orig_args = NULL;
free(input_file); input_file = NULL;
free(output_obj); output_obj = NULL;
+ free(output_dwo); output_dwo = NULL;
free(output_dep); output_dep = NULL;
free(output_cov); output_cov = NULL;
free(output_dia); output_dia = NULL;
free(cached_obj_hash); cached_obj_hash = NULL;
free(cached_obj); cached_obj = NULL;
+ free(cached_dwo); cached_dwo = NULL;
free(cached_stderr); cached_stderr = NULL;
free(cached_dep); cached_dep = NULL;
free(cached_cov); cached_cov = NULL;
output_is_precompiled_header = false;
conf = conf_create();
+ using_split_dwarf = false;
}
/* Make a copy of stderr that will not be cached, so things like
- distcc can send networking errors to it. */
+ * distcc can send networking errors to it. */
static void
setup_uncached_err(void)
{
if (output_dia) {
cc_log("Diagnostic file: %s", output_dia);
}
+
+ if (using_split_dwarf) {
+ if (!generating_dependencies) {
+ assert(output_dwo);
+ }
+ } else {
+ assert(!output_dwo);
+ }
+
+ if (output_dwo) {
+ cc_log("Split dwarf file: %s", output_dwo);
+ }
+
cc_log("Object file: %s", output_obj);
hash_start(&common_hash);
/* run real compiler, sending output to cache */
to_cache(compiler_args);
- exit(0);
+ x_exit(0);
}
static void
case 'h': /* --help */
fputs(USAGE_TEXT, stdout);
- exit(0);
+ x_exit(0);
case 'F': /* --max-files */
- {
- unsigned files;
- initialize();
- files = atoi(optarg);
- if (conf_set_value_in_file(primary_config_path, "max_files", optarg,
- &errmsg)) {
- if (files == 0) {
- printf("Unset cache file limit\n");
- } else {
- printf("Set cache file limit to %u\n", files);
- }
+ {
+ unsigned files;
+ initialize();
+ files = atoi(optarg);
+ if (conf_set_value_in_file(primary_config_path, "max_files", optarg,
+ &errmsg)) {
+ if (files == 0) {
+ printf("Unset cache file limit\n");
} else {
- fatal("could not set cache file limit: %s", errmsg);
+ printf("Set cache file limit to %u\n", files);
}
+ } else {
+ fatal("could not set cache file limit: %s", errmsg);
}
- break;
+ }
+ break;
case 'M': /* --max-size */
- {
- uint64_t size;
- initialize();
- if (!parse_size_with_suffix(optarg, &size)) {
- fatal("invalid size: %s", optarg);
- }
- 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);
- }
+ {
+ uint64_t size;
+ initialize();
+ if (!parse_size_with_suffix(optarg, &size)) {
+ fatal("invalid size: %s", optarg);
+ }
+ if (conf_set_value_in_file(primary_config_path, "max_size", optarg,
+ &errmsg)) {
+ if (size == 0) {
+ printf("Unset cache size limit\n");
} else {
- fatal("could not set cache size limit: %s", errmsg);
+ 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;
+ }
+ break;
case 'o': /* --set-config */
- {
- char *errmsg, *key, *value, *p;
- initialize();
- p = strchr(optarg, '=');
- if (!p) {
- fatal("missing equal sign in \"%s\"", optarg);
- }
- key = x_strndup(optarg, p - optarg);
- value = p + 1;
- if (!conf_set_value_in_file(primary_config_path, key, value, &errmsg)) {
- fatal("%s", errmsg);
- }
- free(key);
+ {
+ char *errmsg, *key, *value, *p;
+ initialize();
+ p = strchr(optarg, '=');
+ if (!p) {
+ fatal("missing equal sign in \"%s\"", optarg);
}
- break;
+ key = x_strndup(optarg, p - optarg);
+ value = p + 1;
+ if (!conf_set_value_in_file(primary_config_path, key, value, &errmsg)) {
+ fatal("%s", errmsg);
+ }
+ free(key);
+ }
+ break;
case 'p': /* --print-config */
initialize();
case 'V': /* --version */
fprintf(stdout, VERSION_TEXT, CCACHE_VERSION);
- exit(0);
+ x_exit(0);
case 'z': /* --zero-stats */
initialize();
default:
fputs(USAGE_TEXT, stderr);
- exit(1);
+ x_exit(1);
}
}
if (same_executable_name(program_name, MYNAME)) {
if (argc < 2) {
fputs(USAGE_TEXT, stderr);
- exit(1);
+ x_exit(1);
}
/* if the first argument isn't an option, then assume we are
- being passed a compiler name and options */
+ * being passed a compiler name and options */
if (argv[1][0] == '-') {
return ccache_main_options(argc, argv);
}
bool is_absolute_path(const char *path);
bool is_full_path(const char *path);
void update_mtime(const char *path);
+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);
}
if (str_startswith(p, ".nfs")) {
- /* Ignore temporary NFS files that may be left for open but deleted files. */
+ /* Ignore temporary NFS files that may be left for open but deleted
+ * files. */
goto out;
}
static const struct compopt compopts[] = {
{"--param", TAKES_ARG},
+ {"--save-temps", TOO_HARD},
{"--serialize-diagnostics", TAKES_ARG | TAKES_PATH},
{"-A", TAKES_ARG},
{"-D", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
{"-fplugin=libcc1plugin", TOO_HARD}, /* interaction with GDB */
{"-frepo", TOO_HARD},
{"-fworking-directory", AFFECTS_CPP},
- {"-gsplit-dwarf", TOO_HARD}, /* generates a .dwo file at the same time */
{"-idirafter", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
{"-iframework", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
{"-imacros", AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
struct compopt key;
key.name = option;
return bsearch(
- &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
- sizeof(compopts[0]), compare_compopts);
+ &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
+ sizeof(compopts[0]), compare_compopts);
}
static const struct compopt *
struct compopt key;
key.name = option;
return bsearch(
- &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
- sizeof(compopts[0]), compare_prefix_compopts);
+ &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
+ sizeof(compopts[0]), compare_prefix_compopts);
}
/* Runs fn on the first two characters of option. */
}
}
-static const char*
+static const char *
bool_to_string(bool value)
{
return value ? "true" : "false";
}
#define ITEM(name, type) \
- parse_##type, offsetof(struct conf, name), NULL
+ parse_ ## type, offsetof(struct conf, name), NULL
#define ITEM_V(name, type, verification) \
- parse_##type, offsetof(struct conf, name), verify_##verification
+ parse_ ## type, offsetof(struct conf, name), verify_ ## verification
#include "confitems_lookup.c"
#include "envtoconfitems_lookup.c"
}
if (!handle_conf_setting(
- conf, env_to_conf_item->conf_name, q, &errmsg2, true, negate,
- "environment")) {
+ conf, env_to_conf_item->conf_name, q, &errmsg2, true, negate,
+ "environment")) {
*errmsg = format("%s: %s", key, errmsg2);
free(errmsg2);
free(key);
extra_libs="zlib/libz.a"
mkdir -p zlib
else
- extra_ldflags="-lz"
+ extra_libs="-lz"
fi
if test x${windows_os} = xyes; then
extra_libs="zlib/libz.a"
mkdir -p zlib
else
- extra_ldflags="-lz"
+ extra_libs="-lz"
fi
dnl Linking on Windows needs ws2_32
$(addprefix $(srcdir)/, $(source_dist_files)) \
$(built_dist_files)
+uncrustify_exclude_files = \
+ getopt_long.c \
+ hashtable.c \
+ hashtable_itr.c \
+ snprintf.c
+
ifneq ($(shell sed 's/.*"\(.*\)".*/\1/' version.c 2>/dev/null),$(version))
$(shell echo 'const char CCACHE_VERSION[] = "$(version)";' >version.c)
endif
check-syntax:
$(CC) $(all_cppflags) -I. $(all_cflags) -S -o /dev/null $(CHK_SOURCES)
+.PHONY: uncrustify
+uncrustify:
+ uncrustify -c uncrustify.cfg --no-backup --replace $(filter-out $(uncrustify_exclude_files), $(base_sources)) $(test_sources)
+
-include .deps/*.d
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);
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+ 0, NULL);
lpDisplayBuf =
- (LPVOID) LocalAlloc(LMEM_ZEROINIT,
- (lstrlen((LPCTSTR) lpMsgBuf)
- + lstrlen((LPCTSTR) __FILE__) + 200)
- * sizeof(TCHAR));
+ (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 %d: %s"), __FILE__, dw, lpMsgBuf);
cc_log("can't execute %s; OS returned error: %s",
- full_path_win_ext, (char*)lpDisplayBuf);
+ full_path_win_ext, (char *)lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
if (!doreturn)
- exit(exitcode);
+ x_exit(exitcode);
return exitcode;
}
#else
-/*
- execute a compiler backend, capturing all output to the given paths
- the full path to the compiler to run is in argv[0]
-*/
+/* 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)
{
close(fd_out);
dup2(fd_err, 2);
close(fd_err);
- exit(execv(argv[0], argv));
+ x_exit(execv(argv[0], argv));
}
close(fd_out);
/*
* 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)
{
/*
- * Copyright (C) 2010, 2012 Joel Rosdahl
+ * Copyright (C) 2010-2015 Joel Rosdahl
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
static void
call_nullary_exit_function(void *context)
{
- struct nullary_exit_function *p = (struct nullary_exit_function*)context;
+ struct nullary_exit_function *p = (struct nullary_exit_function *)context;
p->function();
free(p);
}
exitfn_call(void)
{
struct exit_function *p = exit_functions, *q;
+ exit_functions = NULL;
while (p) {
p->function(p->context);
q = p;
p = p->next;
free(q);
}
- exit_functions = NULL;
}
void
hash_string_length(struct mdfour *md, const char *s, int length)
{
- hash_buffer(md, s, length);
+ hash_buffer(md, s, length);
}
void
file_hashes_equal(struct file_hash *fh1, struct file_hash *fh2)
{
return memcmp(fh1->hash, fh2->hash, 16) == 0
- && fh1->size == fh2->size;
+ && fh1->size == fh2->size;
}
/*
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') {
+ } else if (str[i - 5] == 'T' && str[i - 4] == 'I' &&
+ str[i - 3] == 'M') {
result |= HASH_SOURCE_CODE_FOUND_TIME;
}
}
*/
int
hash_source_code_string(
- struct conf *conf, struct mdfour *hash, const char *str, size_t len,
- const char *path)
+ struct conf *conf, struct mdfour *hash, const char *str, size_t len,
+ const char *path)
{
int result = HASH_SOURCE_CODE_OK;
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;
+ si.hStdError = pipe_out[1];
+ si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ si.dwFlags = STARTF_USESTDHANDLES;
win32args = win32argvtos(sh, args->argv);
ret = CreateProcess(path, win32args, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
CloseHandle(pipe_out[1]);
{".HXX", "c++-header"},
{".tcc", "c++-header"},
{".TCC", "c++-header"},
- {NULL, NULL}};
+ {NULL, NULL}
+};
/*
* Supported languages and corresponding preprocessed languages.
{"objc++-cpp-output", "objective-c++-cpp-output"},
{"objective-c++-header", "objective-c++-cpp-output"},
{"objective-c++-cpp-output", "objective-c++-cpp-output"},
- {NULL, NULL}};
+ {NULL, NULL}
+};
/*
* Guess the language of a file based on its extension. Returns NULL if the
static const uint32_t MAX_MANIFEST_FILE_INFO_ENTRIES = 10000;
#define ccache_static_assert(e) \
- do { enum { ccache_static_assert__ = 1/(e) }; } while (false)
+ do { enum { ccache_static_assert__ = 1/(e) }; } while (false)
struct file_info {
/* Index to n_files. */
}
#define READ_BYTE(var) \
- do { \
+ do { \
int ch_; \
ch_ = gzgetc(f); \
if (ch_ == EOF) { \
} while (false)
#define READ_INT(size, var) \
- do { \
+ do { \
int ch_; \
size_t i_; \
(var) = 0; \
} while (false)
#define READ_STR(var) \
- do { \
+ do { \
char buf_[1024]; \
size_t i_; \
int ch_; \
} while (false)
#define READ_BYTES(n, var) \
- do { \
+ do { \
size_t i_; \
int ch_; \
for (i_ = 0; i_ < (n); i_++) { \
for (i = 0; i < mf->n_objects; i++) {
READ_INT(4, mf->objects[i].n_file_info_indexes);
mf->objects[i].file_info_indexes =
- x_calloc(mf->objects[i].n_file_info_indexes,
- sizeof(*mf->objects[i].file_info_indexes));
+ x_calloc(mf->objects[i].n_file_info_indexes,
+ sizeof(*mf->objects[i].file_info_indexes));
for (j = 0; j < mf->objects[i].n_file_info_indexes; j++) {
READ_INT(4, mf->objects[i].file_info_indexes[j]);
}
}
#define WRITE_INT(size, var) \
- do { \
+ do { \
uint8_t ch_; \
size_t i_; \
for (i_ = 0; i_ < (size); i_++) { \
} while (false)
#define WRITE_STR(var) \
- do { \
+ do { \
if (gzputs(f, var) == EOF || gzputc(f, '\0') == EOF) { \
goto error; \
} \
} while (false)
#define WRITE_BYTES(n, var) \
- do { \
+ do { \
size_t i_; \
for (i_ = 0; i_ < (n); i_++) { \
if (gzputc(f, (var)[i_]) == EOF) { \
&& MAX(st->mtime, st->ctime) >= time_of_compilation) {
cc_log("size/mtime/ctime hit for %s", path);
continue;
- }
- else {
+ } else {
cc_log("size/mtime/ctime miss for %s", path);
}
}
&& 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 {
+ } else {
fi.mtime = -1;
fi.ctime = -1;
}
for (i = 0; i < mf->n_objects; ++i) {
char *hash;
fprintf(stream, " %u:\n", i);
- fprintf(stream, " File hash indexes:");
+ fprintf(stream, " File info indexes:");
for (j = 0; j < mf->objects[i].n_file_info_indexes; ++j) {
fprintf(stream, " %u", mf->objects[i].file_info_indexes[j]);
}
#define MASK32 (0xffffffff)
-#define F(X,Y,Z) ((((X)&(Y)) | ((~(X))&(Z))))
-#define G(X,Y,Z) ((((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))))
-#define H(X,Y,Z) (((X)^(Y)^(Z)))
-#define lshift(x,s) (((((x)<<(s))&MASK32) | (((x)>>(32-(s)))&MASK32)))
-
-#define ROUND1(a,b,c,d,k,s) a = lshift((a + F(b,c,d) + M[k])&MASK32, s)
-#define ROUND2(a,b,c,d,k,s) a = lshift((a + G(b,c,d) + M[k] + 0x5A827999)&MASK32,s)
-#define ROUND3(a,b,c,d,k,s) a = lshift((a + H(b,c,d) + M[k] + 0x6ED9EBA1)&MASK32,s)
+#define F(X, Y, Z) ((((X)&(Y)) | ((~(X))&(Z))))
+#define G(X, Y, Z) ((((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z))))
+#define H(X, Y, Z) (((X)^(Y)^(Z)))
+#define lshift(x, s) (((((x)<<(s))&MASK32) | (((x)>>(32-(s)))&MASK32)))
+
+#define ROUND1(a, b, c, d, k, s) \
+ a = lshift((a + F(b, c, d) + M[k])&MASK32, s)
+#define ROUND2(a, b, c, d, k, s) \
+ a = lshift((a + G(b, c, d) + M[k] + 0x5A827999)&MASK32, s)
+#define ROUND3(a, b, c, d, k, s) \
+ a = lshift((a + H(b, c, d) + M[k] + 0x6ED9EBA1)&MASK32, s)
/* this applies md4 to 64 byte chunks */
static void
mdfour64(uint32_t *M)
{
uint32_t AA, BB, CC, DD;
- uint32_t A,B,C,D;
+ uint32_t A, B, C, D;
A = m->A; B = m->B; C = m->C; D = m->D;
AA = A; BB = B; CC = C; DD = D;
- ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
- ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
- ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
- ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
- ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
- ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
- ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
- ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
-
-
- ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
- ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
- ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
- ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
- ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
- ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
- ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
- ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
-
- ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
- ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
- ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
- ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
- ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
- ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
- ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
- ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
+ ROUND1(A, B, C, D, 0, 3); ROUND1(D, A, B, C, 1, 7);
+ ROUND1(C, D, A, B, 2, 11); ROUND1(B, C, D, A, 3, 19);
+ ROUND1(A, B, C, D, 4, 3); ROUND1(D, A, B, C, 5, 7);
+ ROUND1(C, D, A, B, 6, 11); ROUND1(B, C, D, A, 7, 19);
+ ROUND1(A, B, C, D, 8, 3); ROUND1(D, A, B, C, 9, 7);
+ ROUND1(C, D, A, B, 10, 11); ROUND1(B, C, D, A, 11, 19);
+ ROUND1(A, B, C, D, 12, 3); ROUND1(D, A, B, C, 13, 7);
+ ROUND1(C, D, A, B, 14, 11); ROUND1(B, C, D, A, 15, 19);
+
+
+ ROUND2(A, B, C, D, 0, 3); ROUND2(D, A, B, C, 4, 5);
+ ROUND2(C, D, A, B, 8, 9); ROUND2(B, C, D, A, 12, 13);
+ ROUND2(A, B, C, D, 1, 3); ROUND2(D, A, B, C, 5, 5);
+ ROUND2(C, D, A, B, 9, 9); ROUND2(B, C, D, A, 13, 13);
+ ROUND2(A, B, C, D, 2, 3); ROUND2(D, A, B, C, 6, 5);
+ ROUND2(C, D, A, B, 10, 9); ROUND2(B, C, D, A, 14, 13);
+ ROUND2(A, B, C, D, 3, 3); ROUND2(D, A, B, C, 7, 5);
+ ROUND2(C, D, A, B, 11, 9); ROUND2(B, C, D, A, 15, 13);
+
+ ROUND3(A, B, C, D, 0, 3); ROUND3(D, A, B, C, 8, 9);
+ ROUND3(C, D, A, B, 4, 11); ROUND3(B, C, D, A, 12, 15);
+ ROUND3(A, B, C, D, 2, 3); ROUND3(D, A, B, C, 10, 9);
+ ROUND3(C, D, A, B, 6, 11); ROUND3(B, C, D, A, 14, 15);
+ ROUND3(A, B, C, D, 1, 3); ROUND3(D, A, B, C, 9, 9);
+ ROUND3(C, D, A, B, 5, 11); ROUND3(B, C, D, A, 13, 15);
+ ROUND3(A, B, C, D, 3, 3); ROUND3(D, A, B, C, 11, 9);
+ ROUND3(C, D, A, B, 7, 11); ROUND3(B, C, D, A, 15, 15);
A += AA; B += BB;
C += CC; D += DD;
for (i = 0; i < 16; i++)
M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
- (in[i*4+1]<<8) | (in[i*4+0]<<0);
+ (in[i*4+1]<<8) | (in[i*4+0]<<0);
#else
memcpy(M, in, 16*4);
#endif
#ifdef CCACHE_DEBUG_HASH
if (getenv("CCACHE_DEBUG_HASH")) {
- FILE* f = fopen("ccache-debug-hash.bin", "a");
+ FILE *f = fopen("ccache-debug-hash.bin", "a");
fwrite(in, 1, n, f);
fclose(f);
}
while (len >= 4) {
unsigned int k;
- k = data[0];
+ k = data[0];
k |= data[1] << 8;
k |= data[2] << 16;
k |= data[3] << 24;
case 3: h ^= data[2] << 16;
case 2: h ^= data[1] << 8;
case 1: h ^= data[0];
- h *= m;
+ h *= m;
};
h ^= h >> 13;
{ STATS_DEVICE, "output to a non-regular file ", NULL, 0 },
{ STATS_NOINPUT, "no input file ", NULL, 0 },
{ STATS_BADEXTRAFILE, "error hashing extra file ", NULL, 0 },
- { STATS_NUMFILES, "files in cache ", NULL, FLAG_NOZERO|FLAG_ALWAYS },
- { STATS_TOTALSIZE, "cache size ", display_size_times_1024 , FLAG_NOZERO|FLAG_ALWAYS },
- { STATS_OBSOLETE_MAXFILES, "OBSOLETE", NULL, FLAG_NOZERO|FLAG_NEVER},
- { STATS_OBSOLETE_MAXSIZE, "OBSOLETE", NULL, FLAG_NOZERO|FLAG_NEVER},
+ { STATS_NUMFILES, "files in cache ", NULL,
+ FLAG_NOZERO|FLAG_ALWAYS },
+ { STATS_TOTALSIZE, "cache size ",
+ display_size_times_1024, FLAG_NOZERO|FLAG_ALWAYS },
+ { STATS_OBSOLETE_MAXFILES, "OBSOLETE", NULL,
+ FLAG_NOZERO|FLAG_NEVER},
+ { STATS_OBSOLETE_MAXSIZE, "OBSOLETE", NULL,
+ FLAG_NOZERO|FLAG_NEVER},
{ STATS_NONE, NULL, NULL, 0 }
};
mkdir -p $dir
i=0
while [ $i -lt 10 ]; do
- perl -e 'print "A" x 4017' >$dir/result$i-4017.o
+ printf '%4017s' '' | tr ' ' 'A' >$dir/result$i-4017.o
touch $dir/result$i-4017.stderr
touch $dir/result$i-4017.d
if [ $i -gt 5 ]; then
static const char COLOR_GREEN[] = "\x1b[32m";
static const char COLOR_RED[] = "\x1b[31m";
-#define COLOR(tty, color) ((tty) ? COLOR_##color : "")
+#define COLOR(tty, color) ((tty) ? COLOR_ ## color : "")
static int
is_tty(int fd)
#include "getopt_long.h"
#endif
-#define SUITE(name) unsigned suite_##name(unsigned);
+#define SUITE(name) unsigned suite_ ## name(unsigned);
#include "test/suites.h"
#undef SUITE
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)
{
suite_fn suites[] = {
-#define SUITE(name) &suite_##name,
+#define SUITE(name) &suite_ ## name,
#include "test/suites.h"
#undef SUITE
NULL
{
struct args *args;
const char *argtext =
- "first\rsec\\\tond\tthi\\\\rd\nfourth \tfif\\ th \"si'x\\\" th\""
- " 'seve\nth'\\";
+ "first\rsec\\\tond\tthi\\\\rd\nfourth \tfif\\ th \"si'x\\\" th\""
+ " 'seve\nth'\\";
create_file("gcc_atfile", argtext);
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));
+ "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));
+ "first one alpha beta gamma second beta gamma fourth fifth",
+ args_to_string(args));
CHECK_INT_EQ(10, args->argc);
args_free(args);
" -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 "\
+ " -fno-working-directory -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 " -c foo.c -o foo.o");
struct args *exp_cpp = args_init_from_string(CMD);
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");
+ "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");
+ "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", "");
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");
+ "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");
+ "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", "");
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");
+ "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");
+ "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", "");
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");
+ "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");
+ "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", "");
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");
+ "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");
+ "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", "");
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");
+ "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");
+ "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", "");
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");
+ "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");
+ "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", "");
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");
+ "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");
+ "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", "");
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");
+ "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;
TEST(fprofile_flag_with_nonexisting_dir_not_be_rewritten)
{
struct args *orig = args_init_from_string(
- "gcc -c -fprofile-generate=some/dir foo.c");
+ "gcc -c -fprofile-generate=some/dir foo.c");
struct args *exp_cpp = args_init_from_string(
- "gcc -fprofile-generate=some/dir");
+ "gcc -fprofile-generate=some/dir");
struct args *exp_cc = args_init_from_string(
- "gcc -fprofile-generate=some/dir -c");
+ "gcc -fprofile-generate=some/dir -c");
struct args *act_cpp = NULL, *act_cc = NULL;
create_file("foo.c", "");
user = getenv("USER");
CHECK_STR_EQ("rabbit", user);
create_file(
- "ccache.conf",
- "base_dir = /$USER/foo/${USER} \n"
- "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=true\n"
- "compression_level= 2\n"
- "cpp_extension = .foo\n"
- "direct_mode = false\n"
- "disable = true\n"
- "extra_files_to_hash = a:b c:$USER\n"
- "hard_link = true\n"
- "hash_dir = true\n"
- "log_file = $USER${USER} \n"
- "max_files = 17\n"
- "max_size = 123M\n"
- "path = $USER.x\n"
- "prefix_command = x$USER\n"
- "read_only = true\n"
- "read_only_direct = true\n"
- "recache = true\n"
- "run_second_cpp = true\n"
- "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches pch_defines \n"
- "stats = false\n"
- "temporary_dir = ${USER}_foo\n"
- "umask = 777\n"
- "unify = true"); /* Note: no newline */
+ "ccache.conf",
+ "base_dir = /$USER/foo/${USER} \n"
+ "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=true\n"
+ "compression_level= 2\n"
+ "cpp_extension = .foo\n"
+ "direct_mode = false\n"
+ "disable = true\n"
+ "extra_files_to_hash = a:b c:$USER\n"
+ "hard_link = true\n"
+ "hash_dir = true\n"
+ "log_file = $USER${USER} \n"
+ "max_files = 17\n"
+ "max_size = 123M\n"
+ "path = $USER.x\n"
+ "prefix_command = x$USER\n"
+ "read_only = true\n"
+ "read_only_direct = true\n"
+ "recache = true\n"
+ "run_second_cpp = true\n"
+ "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches pch_defines \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);
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);
+ 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);
+ CHECK_STR_EQ_FREE2(
+ "ccache.conf:1: cache directory levels must be between 1 and 8",
+ errmsg);
conf_free(conf);
}
true,
true,
SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
- SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
- SLOPPY_FILE_STAT_MATCHES,
+ SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
+ SLOPPY_FILE_STAT_MATCHES,
false,
"td",
022,
CHECK_STR_EQ_FREE2("d9130a8164549fe818874806e1c7014b-14", hash_result(&h));
hash_start(&h);
- hash_string(&h, "12345678901234567890123456789012345678901234567890123456789012345678901234567890");
+ hash_string(
+ &h,
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890");
CHECK_STR_EQ_FREE2("e33b4ddc9c38f2199c3e7b164fcc0536-80", hash_result(&h));
}
TEST(check_for_temporal_macros)
{
const char time_start[] =
- "__TIME__\n"
- "int a;\n";
+ "__TIME__\n"
+ "int a;\n";
const char time_middle[] =
- "#define a __TIME__\n"
- "int a;\n";
+ "#define a __TIME__\n"
+ "int a;\n";
const char time_end[] =
- "#define a __TIME__";
+ "#define a __TIME__";
const char date_start[] =
- "__DATE__\n"
- "int ab;\n";
+ "__DATE__\n"
+ "int ab;\n";
const char date_middle[] =
- "#define ab __DATE__\n"
- "int ab;\n";
+ "#define ab __DATE__\n"
+ "int ab;\n";
const char date_end[] =
- "#define ab __DATE__";
+ "#define ab __DATE__";
const char no_temporal[] =
- "#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";
+ "#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));
/*
- * Copyright (C) 2010-2014 Joel Rosdahl
+ * Copyright (C) 2010-2015 Joel Rosdahl
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
TEST(format_hash_as_string)
{
unsigned char hash[16] = {
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"};
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ };
CHECK_STR_EQ_FREE2("00000000000000000000000000000000",
format_hash_as_string(hash, -1));
TEST(subst_env_in_string)
{
char *errmsg;
- const char *shell = getenv("SHELL");
- errmsg = "";
- CHECK_STR_EQ_FREE2(shell,
- subst_env_in_string("$SHELL", &errmsg));
+ putenv("FOO=bar");
+
+ CHECK_STR_EQ_FREE2("bar",
+ subst_env_in_string("$FOO", &errmsg));
CHECK(!errmsg);
errmsg = "";
CHECK(!errmsg);
errmsg = "";
- CHECK_STR_EQ_FREE12(format("%s %s:%s", shell, shell, shell),
- subst_env_in_string("$SHELL $SHELL:$SHELL", &errmsg));
+ CHECK_STR_EQ_FREE2("bar bar:bar",
+ subst_env_in_string("$FOO $FOO:$FOO", &errmsg));
CHECK(!errmsg);
errmsg = "";
- CHECK_STR_EQ_FREE12(format("x%s", shell),
- subst_env_in_string("x$SHELL", &errmsg));
+ CHECK_STR_EQ_FREE2("xbar",
+ subst_env_in_string("x$FOO", &errmsg));
CHECK(!errmsg);
errmsg = "";
- CHECK_STR_EQ_FREE12(format("%sx", shell),
- subst_env_in_string("${SHELL}x", &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("${SHELL", &errmsg));
- CHECK_STR_EQ_FREE2("syntax error: missing '}' after \"SHELL\"", 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("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));
+ "17.1G",
+ format_parsable_size_with_suffix(17.11 * 1000 * 1000 * 1000));
}
TEST(parse_size_with_suffix)
#include "test/util.h"
#ifdef _WIN32
-# define lstat(a,b) stat(a,b)
+# define lstat(a, b) stat(a, b)
#endif
bool
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ */
/*
* C/C++ unifier
build_table();
- for (ofs = 0; ofs < size;) {
+ for (ofs = 0; ofs < size; ) {
if (p[ofs] == '#') {
if ((size-ofs) > 2 && p[ofs+1] == ' ' && isdigit(p[ofs+2])) {
do {
pushchar(hash, p[ofs]);
ofs++;
} while (ofs < size &&
- ((tokens[p[ofs]].type & C_DIGIT) || p[ofs] == '.'));
+ ((tokens[p[ofs]].type & C_DIGIT) || p[ofs] == '.'));
if (ofs < size && (p[ofs] == 'x' || p[ofs] == 'X')) {
do {
pushchar(hash, p[ofs]);
/* hash a file that consists of preprocessor output, but remove any line
number information from the hash
-*/
+ */
int
unify_hash(struct mdfour *hash, const char *fname)
{
if (log_updated_time) {
gettimeofday(&tv, NULL);
#ifdef __MINGW64_VERSION_MAJOR
- tm = localtime((time_t*)&tv.tv_sec);
+ tm = localtime((time_t *)&tv.tv_sec);
#else
tm = localtime(&tv.tv_sec);
#endif
/* 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));
- exit(EXIT_FAILURE);
+ x_exit(EXIT_FAILURE);
}
static void
fputs(prefix, logfile);
print_command(logfile, argv);
rc = fflush(logfile);
- if (rc)
+ if (rc) {
warn_log_fail();
+ }
}
/* something went badly wrong! */
cc_log("FATAL: %s", msg);
fprintf(stderr, "ccache: error: %s\n", msg);
- exit(1);
+ x_exit(1);
}
/*
DWORD dw = last_error;
FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf, 0, NULL);
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf, 0, NULL);
lpDisplayBuf = (LPVOID) LocalAlloc(
- LMEM_ZEROINIT,
- (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 200)
- * sizeof(TCHAR));
+ LMEM_ZEROINIT,
+ (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 200)
+ * sizeof(TCHAR));
_snprintf((LPTSTR) lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"), __FILE__, dw,
lpMsgBuf);
- cc_log("can't get hostname OS returned error: %s", (char*)lpDisplayBuf);
+ cc_log("can't get hostname OS returned error: %s", (char *)lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
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"
- "# http://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"
+ "# http://www.brynosaurus.com/cachedir/\n";
int
create_cachedirtag(const char *dir)
return ptr;
}
-/*
- this is like strdup() but dies if the malloc fails
-*/
+/* This is like strdup() but dies if the malloc fails. */
char *
x_strdup(const char *s)
{
return ret;
}
-/*
- this is like strndup() but dies if the malloc fails
-*/
+/* This is like strndup() but dies if the malloc fails. */
char *
x_strndup(const char *s, size_t n)
{
return ret;
}
-/*
- this is like malloc() but dies if the malloc fails
-*/
+/* This is like malloc() but dies if the malloc fails. */
void *
x_malloc(size_t size)
{
return ret;
}
-/*
- this is like realloc() but dies if the malloc fails
-*/
+/* This is like realloc() but dies if the malloc fails. */
void *
x_realloc(void *ptr, size_t size)
{
}
-/*
- a sane realpath() function, trying to cope with stupid path limits and
- a broken API
-*/
+/* A sane realpath() function, trying to cope with stupid path limits and a
+ * broken API. */
char *
x_realpath(const char *path)
{
p = realpath(path, ret);
#elif defined(_WIN32)
path_handle = CreateFile(
- path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
+ path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE != path_handle) {
GetFinalPathNameByHandle(path_handle, ret, maxlen, FILE_NAME_NORMALIZED);
CloseHandle(path_handle);
ret = strtok(str, delim);
if (ret) {
char *save = ret;
- while (*save++);
+ while (*save++) ;
if ((len + 1) == (intptr_t) (save - str))
save--;
*saveptr = save;
}
/*
- * Rename oldpath to newpath (deleting newpath).
+ * If exit() already has been called, call _exit(), otherwise exit(). This is
+ * used to avoid calling exit() inside an atexit handler.
*/
+void
+x_exit(int 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)
{
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);
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+ 0, NULL);
lpDisplayBuf = (LPVOID) LocalAlloc(
- LMEM_ZEROINIT,
- (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 40)
- * sizeof(TCHAR));
+ LMEM_ZEROINIT,
+ (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 40)
+ * sizeof(TCHAR));
_snprintf((LPTSTR) lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf);
cc_log("can't rename file %s to %s OS returned error: %s",
- oldpath, newpath, (char*) lpDisplayBuf);
+ oldpath, newpath, (char *) lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
-const char CCACHE_VERSION[] = "3.2.2";
+const char CCACHE_VERSION[] = "3.2.3";