Commit 62bf296a9c0f5be492f0677ed111b3fa217f4c11

Authored by Jay Berkenbilt
1 parent 92b69246

Make assert handling less error-prone

Prevent my future self or other contributors from using assert in
tests and then having that assert not do anything because of the
NDEBUG macro.
CMakeLists.txt
@@ -305,6 +305,10 @@ if(GENERATE_AUTO_JOB) @@ -305,6 +305,10 @@ if(GENERATE_AUTO_JOB)
305 add_custom_target(auto_job_files ALL DEPENDS ${auto_job_outputs}) 305 add_custom_target(auto_job_files ALL DEPENDS ${auto_job_outputs})
306 endif() 306 endif()
307 307
  308 +add_test(
  309 + NAME check-assert
  310 + COMMAND perl ${qpdf_SOURCE_DIR}/check_assert)
  311 +
308 # add_subdirectory order affects test order 312 # add_subdirectory order affects test order
309 add_subdirectory(include) 313 add_subdirectory(include)
310 add_subdirectory(libqpdf) 314 add_subdirectory(libqpdf)
README-maintainer
@@ -123,11 +123,23 @@ CODING RULES @@ -123,11 +123,23 @@ CODING RULES
123 "Code Formatting" section in manual/contributing.rst for details. 123 "Code Formatting" section in manual/contributing.rst for details.
124 See also "CODE FORMATTING" below. 124 See also "CODE FORMATTING" below.
125 125
126 -* Do not use assert in non-test code for any purpose other than as a  
127 - sanity check during development that would be safe to remove in  
128 - production. assert is for strong invariant checking. When developing  
129 - and using assert for that purpose, make sure to use the Debug  
130 - configuration since assert is disabled in other configurations. 126 +* Use of assert:
  127 +
  128 + * Test code: #include <qpdf/assert_test.h> first.
  129 + * Debug code: #include <qpdf/assert_debug.h> first and use
  130 + qpdf_assert_debug instead of assert.
  131 +
  132 + These rules are enforced by the check-assert test. This practices
  133 + serves to
  134 +
  135 + * remind us that assert in release code disappears and so should only
  136 + be used for debugging; when doing so use a Debug build
  137 + configuration
  138 +
  139 + * protect us from using assert in test code without explicitly
  140 + removing the NDEBUG definition, since that would cause the assert
  141 + not to actually be testing anything in non-Debug build
  142 + configurations.
131 143
132 * In a source file, include the header file that declares the source 144 * In a source file, include the header file that declares the source
133 class first followed by a blank line. If a config file is needed 145 class first followed by a blank line. If a config file is needed
check_assert 0 → 100755
  1 +#!/usr/bin/env perl
  2 +require 5.008;
  3 +use warnings;
  4 +use strict;
  5 +use File::Basename;
  6 +
  7 +my $whoami = basename($0);
  8 +chdir(dirname($0)) or die;
  9 +
  10 +my $errors = 0;
  11 +foreach my $file (glob('*/*.c'), glob('*/*.cc'),
  12 + glob('*/*/*.h'), glob('*/*/*.hh'))
  13 +{
  14 + my $assert_test = 0;
  15 + if ($file =~ m,^libqpdf/qpdf/assert_,)
  16 + {
  17 + next;
  18 + }
  19 + open(F, "<$file") or die;
  20 + my $first_include = undef;
  21 + while (<F>)
  22 + {
  23 + if (m,^\s*#\s*include <qpdf/assert_(.*?).h>,)
  24 + {
  25 + if ($1 eq 'test')
  26 + {
  27 + $assert_test = 1;
  28 + }
  29 + if (defined $first_include)
  30 + {
  31 + error("$file:$.: qpdf/assert header must be first");
  32 + }
  33 + }
  34 + if (m,^\s*#\s*include <(.*?)>,)
  35 + {
  36 + my $header = $1;
  37 + if (($header eq 'cassert') || ($header eq 'assert.h'))
  38 + {
  39 + error("$file:$.: assert.h and cassert are not allowed --" .
  40 + " use one of the qpdf/assert_ files instead");
  41 + }
  42 + $first_include = 1;
  43 + }
  44 + if ((! $assert_test) && (m/assert\(/))
  45 + {
  46 + error("$file:$.: call qpdf_assert_debug instead of assert");
  47 + }
  48 + }
  49 + close(F);
  50 +}
  51 +if ($errors)
  52 +{
  53 + die "$whoami: errors detected\n";
  54 +}
  55 +print "$whoami: no incorrect use of assert found\n";
  56 +
  57 +sub error
  58 +{
  59 + my $msg = shift;
  60 + warn $msg, "\n";
  61 + $errors = 1;
  62 +}
include/qpdf/QIntC.hh
@@ -24,7 +24,6 @@ @@ -24,7 +24,6 @@
24 24
25 #include <qpdf/DLL.h> 25 #include <qpdf/DLL.h>
26 #include <qpdf/Types.h> 26 #include <qpdf/Types.h>
27 -#include <cassert>  
28 #include <iostream> 27 #include <iostream>
29 #include <limits> 28 #include <limits>
30 #include <locale> 29 #include <locale>
libqpdf/QPDFWriter.cc
1 -#include <qpdf/qpdf-config.h> // include first for large file support 1 +#include <qpdf/assert_debug.h>
  2 +
  3 +#include <qpdf/qpdf-config.h> // include early for large file support
2 4
3 #include <qpdf/QPDFWriter.hh> 5 #include <qpdf/QPDFWriter.hh>
4 6
@@ -21,7 +23,6 @@ @@ -21,7 +23,6 @@
21 #include <qpdf/RC4.hh> 23 #include <qpdf/RC4.hh>
22 24
23 #include <algorithm> 25 #include <algorithm>
24 -#include <cassert>  
25 #include <stdlib.h> 26 #include <stdlib.h>
26 27
27 QPDFWriter::Members::Members(QPDF& pdf) : 28 QPDFWriter::Members::Members(QPDF& pdf) :
@@ -996,7 +997,7 @@ QPDFWriter::writePad(int nspaces) @@ -996,7 +997,7 @@ QPDFWriter::writePad(int nspaces)
996 Pipeline* 997 Pipeline*
997 QPDFWriter::pushPipeline(Pipeline* p) 998 QPDFWriter::pushPipeline(Pipeline* p)
998 { 999 {
999 - assert(dynamic_cast<Pl_Count*>(p) == 0); 1000 + qpdf_assert_debug(dynamic_cast<Pl_Count*>(p) == 0);
1000 this->m->pipeline_stack.push_back(p); 1001 this->m->pipeline_stack.push_back(p);
1001 return p; 1002 return p;
1002 } 1003 }
@@ -1027,9 +1028,9 @@ QPDFWriter::PipelinePopper::~PipelinePopper() @@ -1027,9 +1028,9 @@ QPDFWriter::PipelinePopper::~PipelinePopper()
1027 if (stack_id.empty()) { 1028 if (stack_id.empty()) {
1028 return; 1029 return;
1029 } 1030 }
1030 - assert(qw->m->pipeline_stack.size() >= 2); 1031 + qpdf_assert_debug(qw->m->pipeline_stack.size() >= 2);
1031 qw->m->pipeline->finish(); 1032 qw->m->pipeline->finish();
1032 - assert( 1033 + qpdf_assert_debug(
1033 dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) == 1034 dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) ==
1034 qw->m->pipeline); 1035 qw->m->pipeline);
1035 // It might be possible for this assertion to fail if 1036 // It might be possible for this assertion to fail if
@@ -1038,7 +1039,7 @@ QPDFWriter::PipelinePopper::~PipelinePopper() @@ -1038,7 +1039,7 @@ QPDFWriter::PipelinePopper::~PipelinePopper()
1038 // which two dynamically allocated PipelinePopper objects ever 1039 // which two dynamically allocated PipelinePopper objects ever
1039 // exist at the same time, so the assertion will fail if they get 1040 // exist at the same time, so the assertion will fail if they get
1040 // popped out of order from automatic destruction. 1041 // popped out of order from automatic destruction.
1041 - assert(qw->m->pipeline->getIdentifier() == stack_id); 1042 + qpdf_assert_debug(qw->m->pipeline->getIdentifier() == stack_id);
1042 delete qw->m->pipeline_stack.back(); 1043 delete qw->m->pipeline_stack.back();
1043 qw->m->pipeline_stack.pop_back(); 1044 qw->m->pipeline_stack.pop_back();
1044 while (dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) == 0) { 1045 while (dynamic_cast<Pl_Count*>(qw->m->pipeline_stack.back()) == 0) {
@@ -1109,9 +1110,9 @@ QPDFWriter::pushMD5Pipeline(PipelinePopper&amp; pp) @@ -1109,9 +1110,9 @@ QPDFWriter::pushMD5Pipeline(PipelinePopper&amp; pp)
1109 throw std::logic_error("Deterministic ID computation enabled after ID" 1110 throw std::logic_error("Deterministic ID computation enabled after ID"
1110 " generation has already occurred."); 1111 " generation has already occurred.");
1111 } 1112 }
1112 - assert(this->m->deterministic_id);  
1113 - assert(this->m->md5_pipeline == 0);  
1114 - assert(this->m->pipeline->getCount() == 0); 1113 + qpdf_assert_debug(this->m->deterministic_id);
  1114 + qpdf_assert_debug(this->m->md5_pipeline == 0);
  1115 + qpdf_assert_debug(this->m->pipeline->getCount() == 0);
1115 this->m->md5_pipeline = new Pl_MD5("qpdf md5", this->m->pipeline); 1116 this->m->md5_pipeline = new Pl_MD5("qpdf md5", this->m->pipeline);
1116 this->m->md5_pipeline->persistAcrossFinish(true); 1117 this->m->md5_pipeline->persistAcrossFinish(true);
1117 // Special case code in popPipelineStack clears this->m->md5_pipeline 1118 // Special case code in popPipelineStack clears this->m->md5_pipeline
@@ -1123,8 +1124,8 @@ QPDFWriter::pushMD5Pipeline(PipelinePopper&amp; pp) @@ -1123,8 +1124,8 @@ QPDFWriter::pushMD5Pipeline(PipelinePopper&amp; pp)
1123 void 1124 void
1124 QPDFWriter::computeDeterministicIDData() 1125 QPDFWriter::computeDeterministicIDData()
1125 { 1126 {
1126 - assert(this->m->md5_pipeline != 0);  
1127 - assert(this->m->deterministic_id_data.empty()); 1127 + qpdf_assert_debug(this->m->md5_pipeline != 0);
  1128 + qpdf_assert_debug(this->m->deterministic_id_data.empty());
1128 this->m->deterministic_id_data = this->m->md5_pipeline->getHexDigest(); 1129 this->m->deterministic_id_data = this->m->md5_pipeline->getHexDigest();
1129 this->m->md5_pipeline->enable(false); 1130 this->m->md5_pipeline->enable(false);
1130 } 1131 }
@@ -1786,7 +1787,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) @@ -1786,7 +1787,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object)
1786 // object stream that we are generating from scratch. 1787 // object stream that we are generating from scratch.
1787 1788
1788 QPDFObjGen old_og = object.getObjGen(); 1789 QPDFObjGen old_og = object.getObjGen();
1789 - assert(old_og.getGen() == 0); 1790 + qpdf_assert_debug(old_og.getGen() == 0);
1790 int old_id = old_og.getObj(); 1791 int old_id = old_og.getObj();
1791 int new_id = this->m->obj_renumber[old_og]; 1792 int new_id = this->m->obj_renumber[old_og];
1792 1793
@@ -3003,7 +3004,7 @@ QPDFWriter::writeLinearized() @@ -3003,7 +3004,7 @@ QPDFWriter::writeLinearized()
3003 closeObject(lindict_id); 3004 closeObject(lindict_id);
3004 static int const pad = 200; 3005 static int const pad = 200;
3005 int spaces = QIntC::to_int(pos - this->m->pipeline->getCount() + pad); 3006 int spaces = QIntC::to_int(pos - this->m->pipeline->getCount() + pad);
3006 - assert(spaces >= 0); 3007 + qpdf_assert_debug(spaces >= 0);
3007 writePad(spaces); 3008 writePad(spaces);
3008 writeString("\n"); 3009 writeString("\n");
3009 3010
@@ -3177,7 +3178,7 @@ QPDFWriter::writeLinearized() @@ -3177,7 +3178,7 @@ QPDFWriter::writeLinearized()
3177 need_xref_stream ? 0 : 1); 3178 need_xref_stream ? 0 : 1);
3178 computeDeterministicIDData(); 3179 computeDeterministicIDData();
3179 pp_md5 = 0; 3180 pp_md5 = 0;
3180 - assert(this->m->md5_pipeline == 0); 3181 + qpdf_assert_debug(this->m->md5_pipeline == 0);
3181 } 3182 }
3182 3183
3183 // Close first pass pipeline 3184 // Close first pass pipeline
@@ -3377,6 +3378,6 @@ QPDFWriter::writeStandard() @@ -3377,6 +3378,6 @@ QPDFWriter::writeStandard()
3377 "QPDFWriter standard deterministic ID", 3378 "QPDFWriter standard deterministic ID",
3378 this->m->object_stream_to_objects.empty() ? 0 : 1); 3379 this->m->object_stream_to_objects.empty() ? 0 : 1);
3379 pp_md5 = 0; 3380 pp_md5 = 0;
3380 - assert(this->m->md5_pipeline == 0); 3381 + qpdf_assert_debug(this->m->md5_pipeline == 0);
3381 } 3382 }
3382 } 3383 }
libqpdf/QPDF_encryption.cc
1 // This file implements methods from the QPDF class that involve 1 // This file implements methods from the QPDF class that involve
2 // encryption. 2 // encryption.
3 3
  4 +#include <qpdf/assert_debug.h>
  5 +
4 #include <qpdf/QPDF.hh> 6 #include <qpdf/QPDF.hh>
5 7
6 #include <qpdf/QPDFExc.hh> 8 #include <qpdf/QPDFExc.hh>
@@ -15,7 +17,6 @@ @@ -15,7 +17,6 @@
15 #include <qpdf/RC4.hh> 17 #include <qpdf/RC4.hh>
16 18
17 #include <algorithm> 19 #include <algorithm>
18 -#include <cassert>  
19 #include <string.h> 20 #include <string.h>
20 21
21 static unsigned char const padding_string[] = { 22 static unsigned char const padding_string[] = {
@@ -288,7 +289,7 @@ hash_V5( @@ -288,7 +289,7 @@ hash_V5(
288 289
289 ++round_number; 290 ++round_number;
290 std::string K1 = password + K + udata; 291 std::string K1 = password + K + udata;
291 - assert(K.length() >= 32); 292 + qpdf_assert_debug(K.length() >= 32);
292 std::string E = process_with_aes( 293 std::string E = process_with_aes(
293 K.substr(0, 16), 294 K.substr(0, 16),
294 true, 295 true,
libqpdf/QPDF_optimization.cc
1 // See the "Optimization" section of the manual. 1 // See the "Optimization" section of the manual.
2 2
  3 +#include <qpdf/assert_debug.h>
  4 +
3 #include <qpdf/QPDF.hh> 5 #include <qpdf/QPDF.hh>
4 6
5 #include <qpdf/QPDFExc.hh> 7 #include <qpdf/QPDFExc.hh>
6 #include <qpdf/QPDF_Array.hh> 8 #include <qpdf/QPDF_Array.hh>
7 #include <qpdf/QPDF_Dictionary.hh> 9 #include <qpdf/QPDF_Dictionary.hh>
8 #include <qpdf/QTC.hh> 10 #include <qpdf/QTC.hh>
9 -#include <cassert>  
10 11
11 QPDF::ObjUser::ObjUser() : 12 QPDF::ObjUser::ObjUser() :
12 ou_type(ou_bad), 13 ou_type(ou_bad),
@@ -18,14 +19,14 @@ QPDF::ObjUser::ObjUser(user_e type) : @@ -18,14 +19,14 @@ QPDF::ObjUser::ObjUser(user_e type) :
18 ou_type(type), 19 ou_type(type),
19 pageno(0) 20 pageno(0)
20 { 21 {
21 - assert(type == ou_root); 22 + qpdf_assert_debug(type == ou_root);
22 } 23 }
23 24
24 QPDF::ObjUser::ObjUser(user_e type, int pageno) : 25 QPDF::ObjUser::ObjUser(user_e type, int pageno) :
25 ou_type(type), 26 ou_type(type),
26 pageno(pageno) 27 pageno(pageno)
27 { 28 {
28 - assert((type == ou_page) || (type == ou_thumb)); 29 + qpdf_assert_debug((type == ou_page) || (type == ou_thumb));
29 } 30 }
30 31
31 QPDF::ObjUser::ObjUser(user_e type, std::string const& key) : 32 QPDF::ObjUser::ObjUser(user_e type, std::string const& key) :
@@ -33,7 +34,7 @@ QPDF::ObjUser::ObjUser(user_e type, std::string const&amp; key) : @@ -33,7 +34,7 @@ QPDF::ObjUser::ObjUser(user_e type, std::string const&amp; key) :
33 pageno(0), 34 pageno(0),
34 key(key) 35 key(key)
35 { 36 {
36 - assert((type == ou_trailer_key) || (type == ou_root_key)); 37 + qpdf_assert_debug((type == ou_trailer_key) || (type == ou_root_key));
37 } 38 }
38 39
39 bool 40 bool
libqpdf/qpdf/assert_debug.h 0 → 100644
  1 +/*
  2 + * Include this file to use assert in regular code for
  3 + * debugging/strong sanity checking, knowing that the assert will be
  4 + * disabled in release code. Use qpdf_assert_debug in the code.
  5 + */
  6 +
  7 +/* assert_debug and assert_test intentionally use the same
  8 + * guard. Search for assert in README-MAINTAINER.
  9 + */
  10 +#ifdef QPDF_ASSERT_H
  11 +# error "At most one qpdf/assert header may be included at most one time"
  12 +#else
  13 +# define QPDF_ASSERT_H
  14 +
  15 +# include <assert.h>
  16 +# define qpdf_assert_debug assert
  17 +
  18 +#endif /* QPDF_ASSERT_H */
libqpdf/qpdf/assert_test.h 0 → 100644
  1 +/*
  2 + * Include this file to use assert in regular code for
  3 + * debugging/strong sanity checking, knowing that the assert will be
  4 + * disabled in release code. Use qpdf_debug_assert in the code.
  5 + */
  6 +
  7 +/* assert_debug and assert_test intentionally use the same
  8 + * guard. Search for assert in README-MAINTAINER.
  9 + */
  10 +#ifdef QPDF_ASSERT_H
  11 +# error "At most one qpdf/assert header may be included at most one time"
  12 +#else
  13 +# define QPDF_ASSERT_H
  14 +
  15 +# ifdef NDEBUG
  16 +# undef NDEBUG
  17 +# endif
  18 +# include <assert.h>
  19 +
  20 +#endif /* QPDF_ASSERT_H */
libtests/arg_parser.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/QPDFArgParser.hh> 3 #include <qpdf/QPDFArgParser.hh>
2 #include <qpdf/QPDFUsage.hh> 4 #include <qpdf/QPDFUsage.hh>
3 #include <qpdf/QUtil.hh> 5 #include <qpdf/QUtil.hh>
4 #include <cstring> 6 #include <cstring>
5 #include <iostream> 7 #include <iostream>
6 8
7 -#ifdef NDEBUG  
8 -// We need assert even in a release build for test code.  
9 -# undef NDEBUG  
10 -#endif  
11 -#include <cassert>  
12 -  
13 class ArgParser 9 class ArgParser
14 { 10 {
15 public: 11 public:
libtests/base64.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/Pl_Base64.hh> 3 #include <qpdf/Pl_Base64.hh>
2 4
3 #include <qpdf/Pl_StdioFile.hh> 5 #include <qpdf/Pl_StdioFile.hh>
4 #include <qpdf/QUtil.hh> 6 #include <qpdf/QUtil.hh>
5 -#include <cassert>  
6 #include <cstdlib> 7 #include <cstdlib>
7 #include <cstring> 8 #include <cstring>
8 #include <iostream> 9 #include <iostream>
libtests/buffer.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/Pl_Buffer.hh> 3 #include <qpdf/Pl_Buffer.hh>
2 #include <qpdf/Pl_Count.hh> 4 #include <qpdf/Pl_Count.hh>
3 #include <qpdf/Pl_Discard.hh> 5 #include <qpdf/Pl_Discard.hh>
@@ -7,12 +9,6 @@ @@ -7,12 +9,6 @@
7 #include <stdexcept> 9 #include <stdexcept>
8 #include <stdlib.h> 10 #include <stdlib.h>
9 11
10 -#ifdef NDEBUG  
11 -// We need assert even in a release build for test code.  
12 -# undef NDEBUG  
13 -#endif  
14 -#include <cassert>  
15 -  
16 static unsigned char* 12 static unsigned char*
17 uc(char const* s) 13 uc(char const* s)
18 { 14 {
libtests/concatenate.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/Pl_Buffer.hh> 3 #include <qpdf/Pl_Buffer.hh>
2 #include <qpdf/Pl_Concatenate.hh> 4 #include <qpdf/Pl_Concatenate.hh>
3 #include <qpdf/Pl_Flate.hh> 5 #include <qpdf/Pl_Flate.hh>
4 #include <qpdf/QUtil.hh> 6 #include <qpdf/QUtil.hh>
5 #include <iostream> 7 #include <iostream>
6 8
7 -#ifdef NDEBUG  
8 -// We need assert even in a release build for test code.  
9 -# undef NDEBUG  
10 -#endif  
11 -#include <cassert>  
12 -  
13 static void 9 static void
14 pipeStringAndFinish(Pipeline* p, std::string const& str) 10 pipeStringAndFinish(Pipeline* p, std::string const& str)
15 { 11 {
libtests/cxx11.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <cstdint> 3 #include <cstdint>
2 #include <cstdlib> 4 #include <cstdlib>
3 #include <cstring> 5 #include <cstring>
@@ -9,12 +11,6 @@ @@ -9,12 +11,6 @@
9 #include <type_traits> 11 #include <type_traits>
10 #include <vector> 12 #include <vector>
11 13
12 -#ifdef NDEBUG  
13 -// We need assert even in a release build for test code.  
14 -# undef NDEBUG  
15 -#endif  
16 -#include <cassert>  
17 -  
18 // Functional programming 14 // Functional programming
19 15
20 // Function that returns a callable in the form of a lambda 16 // Function that returns a callable in the form of a lambda
libtests/json.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/JSON.hh> 3 #include <qpdf/JSON.hh>
2 #include <qpdf/QPDFObjectHandle.hh> 4 #include <qpdf/QPDFObjectHandle.hh>
3 #include <iostream> 5 #include <iostream>
4 6
5 -#ifdef NDEBUG  
6 -// We need assert even in a release build for test code.  
7 -# undef NDEBUG  
8 -#endif  
9 -#include <cassert>  
10 -  
11 static void 7 static void
12 check(JSON const& j, std::string const& exp) 8 check(JSON const& j, std::string const& exp)
13 { 9 {
libtests/json_handler.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/JSONHandler.hh> 3 #include <qpdf/JSONHandler.hh>
2 #include <qpdf/QPDFUsage.hh> 4 #include <qpdf/QPDFUsage.hh>
3 #include <qpdf/QUtil.hh> 5 #include <qpdf/QUtil.hh>
4 #include <iostream> 6 #include <iostream>
5 7
6 -#ifdef NDEBUG  
7 -// We need assert even in a release build for test code.  
8 -# undef NDEBUG  
9 -#endif  
10 -#include <cassert>  
11 -  
12 static void 8 static void
13 print_null(std::string const& path) 9 print_null(std::string const& path)
14 { 10 {
libtests/matrix.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/QPDFMatrix.hh> 3 #include <qpdf/QPDFMatrix.hh>
2 #include <qpdf/QUtil.hh> 4 #include <qpdf/QUtil.hh>
3 #include <iostream> 5 #include <iostream>
4 6
5 -#ifdef NDEBUG  
6 -// We need assert even in a release build for test code.  
7 -# undef NDEBUG  
8 -#endif  
9 -#include <cassert>  
10 -  
11 static void 7 static void
12 check(QPDFMatrix const& m, std::string const& exp) 8 check(QPDFMatrix const& m, std::string const& exp)
13 { 9 {
libtests/pdf_version.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/PDFVersion.hh> 3 #include <qpdf/PDFVersion.hh>
2 4
3 #include <iostream> 5 #include <iostream>
4 6
5 -#ifdef NDEBUG  
6 -// We need assert even in a release build for test code.  
7 -# undef NDEBUG  
8 -#endif  
9 -#include <cassert>  
10 -  
11 int 7 int
12 main() 8 main()
13 { 9 {
libtests/predictors.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/Pl_PNGFilter.hh> 3 #include <qpdf/Pl_PNGFilter.hh>
2 #include <qpdf/Pl_StdioFile.hh> 4 #include <qpdf/Pl_StdioFile.hh>
3 #include <qpdf/Pl_TIFFPredictor.hh> 5 #include <qpdf/Pl_TIFFPredictor.hh>
@@ -9,12 +11,6 @@ @@ -9,12 +11,6 @@
9 #include <stdlib.h> 11 #include <stdlib.h>
10 #include <string.h> 12 #include <string.h>
11 13
12 -#ifdef NDEBUG  
13 -// We need assert even in a release build for test code.  
14 -# undef NDEBUG  
15 -#endif  
16 -#include <cassert>  
17 -  
18 void 14 void
19 run(char const* filename, 15 run(char const* filename,
20 char const* filter, 16 char const* filter,
libtests/qintc.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/QIntC.hh> 3 #include <qpdf/QIntC.hh>
2 #include <stdint.h> 4 #include <stdint.h>
3 5
4 -#ifdef NDEBUG  
5 -// We need assert even in a release build for test code.  
6 -# undef NDEBUG  
7 -#endif  
8 -#include <cassert>  
9 -  
10 #define try_convert(exp_pass, fn, i) \ 6 #define try_convert(exp_pass, fn, i) \
11 try_convert_real(#fn "(" #i ")", exp_pass, fn, i) 7 try_convert_real(#fn "(" #i ")", exp_pass, fn, i)
12 8
libtests/qutil.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/Pl_Buffer.hh> 3 #include <qpdf/Pl_Buffer.hh>
2 #include <qpdf/QPDFSystemError.hh> 4 #include <qpdf/QPDFSystemError.hh>
3 #include <qpdf/QUtil.hh> 5 #include <qpdf/QUtil.hh>
@@ -17,12 +19,6 @@ @@ -17,12 +19,6 @@
17 # include <unistd.h> 19 # include <unistd.h>
18 #endif 20 #endif
19 21
20 -#ifdef NDEBUG  
21 -// We need assert even in a release build for test code.  
22 -# undef NDEBUG  
23 -#endif  
24 -#include <cassert>  
25 -  
26 template <class int_T> 22 template <class int_T>
27 void 23 void
28 test_to_number( 24 test_to_number(
libtests/rc4.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/Pl_RC4.hh> 3 #include <qpdf/Pl_RC4.hh>
2 #include <qpdf/Pl_StdioFile.hh> 4 #include <qpdf/Pl_StdioFile.hh>
3 #include <qpdf/QIntC.hh> 5 #include <qpdf/QIntC.hh>
@@ -8,12 +10,6 @@ @@ -8,12 +10,6 @@
8 #include <stdlib.h> 10 #include <stdlib.h>
9 #include <string.h> 11 #include <string.h>
10 12
11 -#ifdef NDEBUG  
12 -// We need assert even in a release build for test code.  
13 -# undef NDEBUG  
14 -#endif  
15 -#include <cassert>  
16 -  
17 static void 13 static void
18 other_tests() 14 other_tests()
19 { 15 {
libtests/sparse_array.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/SparseOHArray.hh> 3 #include <qpdf/SparseOHArray.hh>
2 #include <iostream> 4 #include <iostream>
3 5
4 -#ifdef NDEBUG  
5 -// We need assert even in a release build for test code.  
6 -# undef NDEBUG  
7 -#endif  
8 -#include <cassert>  
9 -  
10 int 6 int
11 main() 7 main()
12 { 8 {
qpdf/CMakeLists.txt
@@ -29,6 +29,16 @@ endforeach() @@ -29,6 +29,16 @@ endforeach()
29 target_include_directories(qpdf-ctest PRIVATE ${CMAKE_BINARY_DIR}/libqpdf) 29 target_include_directories(qpdf-ctest PRIVATE ${CMAKE_BINARY_DIR}/libqpdf)
30 target_include_directories(sizes PRIVATE ${JPEG_INCLUDE}) 30 target_include_directories(sizes PRIVATE ${JPEG_INCLUDE})
31 31
  32 +set(needs_private_headers
  33 + test_large_file
  34 + test_driver
  35 + qpdf-ctest
  36 + qpdfjob-ctest
  37 + )
  38 +foreach(TARGET ${needs_private_headers})
  39 + target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR}/libqpdf)
  40 +endforeach()
  41 +
32 foreach(B qpdf test_unicode_filenames fix-qdf test_shell_glob) 42 foreach(B qpdf test_unicode_filenames fix-qdf test_shell_glob)
33 if(WINDOWS_WMAIN_COMPILE) 43 if(WINDOWS_WMAIN_COMPILE)
34 target_compile_options(${B} PRIVATE ${WINDOWS_WMAIN_COMPILE}) 44 target_compile_options(${B} PRIVATE ${WINDOWS_WMAIN_COMPILE})
qpdf/qpdf-ctest.c
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/qpdf-c.h> 3 #include <qpdf/qpdf-c.h>
2 #include <errno.h> 4 #include <errno.h>
3 #include <stdio.h> 5 #include <stdio.h>
@@ -6,12 +8,6 @@ @@ -6,12 +8,6 @@
6 8
7 #include <qpdf/qpdf-config.h> // for LL_FMT -- special case in build 9 #include <qpdf/qpdf-config.h> // for LL_FMT -- special case in build
8 10
9 -#ifdef NDEBUG  
10 -/* We need assert even in a release build for test code. */  
11 -# undef NDEBUG  
12 -#endif  
13 -#include <assert.h>  
14 -  
15 static char* whoami = 0; 11 static char* whoami = 0;
16 static qpdf_data qpdf = 0; 12 static qpdf_data qpdf = 0;
17 13
qpdf/qpdfjob-ctest.c
  1 +#include <qpdf/assert_test.h>
  2 +
1 #include <qpdf/qpdfjob-c.h> 3 #include <qpdf/qpdfjob-c.h>
2 #include <stdio.h> 4 #include <stdio.h>
3 #include <stdlib.h> 5 #include <stdlib.h>
4 #include <string.h> 6 #include <string.h>
5 7
6 -#ifdef NDEBUG  
7 -/* We need assert even in a release build for test code. */  
8 -# undef NDEBUG  
9 -#endif  
10 -#include <assert.h>  
11 -  
12 #ifndef QPDF_NO_WCHAR_T 8 #ifndef QPDF_NO_WCHAR_T
13 static void 9 static void
14 wide_test() 10 wide_test()
qpdf/test_driver.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 // This program tests miscellaneous functionality in the qpdf library 3 // This program tests miscellaneous functionality in the qpdf library
2 // that we don't want to pollute the qpdf program with. 4 // that we don't want to pollute the qpdf program with.
3 5
@@ -32,12 +34,6 @@ @@ -32,12 +34,6 @@
32 #include <stdlib.h> 34 #include <stdlib.h>
33 #include <string.h> 35 #include <string.h>
34 36
35 -#ifdef NDEBUG  
36 -// We need assert even in a release build for test code.  
37 -# undef NDEBUG  
38 -#endif  
39 -#include <cassert>  
40 -  
41 static char const* whoami = 0; 37 static char const* whoami = 0;
42 38
43 void 39 void
qpdf/test_large_file.cc
  1 +#include <qpdf/assert_test.h>
  2 +
1 // NOTE: This test program doesn't do anything special to enable large 3 // NOTE: This test program doesn't do anything special to enable large
2 // file support. This is important since it verifies that programs 4 // file support. This is important since it verifies that programs
3 // don't have to do anything special -- all the work is done 5 // don't have to do anything special -- all the work is done
@@ -14,12 +16,6 @@ @@ -14,12 +16,6 @@
14 #include <stdlib.h> 16 #include <stdlib.h>
15 #include <string.h> 17 #include <string.h>
16 18
17 -#ifdef NDEBUG  
18 -// We need assert even in a release build for test code.  
19 -# undef NDEBUG  
20 -#endif  
21 -#include <cassert>  
22 -  
23 // Run "test_large_file write small a.pdf" to get a PDF file that you 19 // Run "test_large_file write small a.pdf" to get a PDF file that you
24 // can look at in a reader. 20 // can look at in a reader.
25 21