implemented basics
This commit is contained in:
12
contrib/iniParser/SConscript
Normal file
12
contrib/iniParser/SConscript
Normal file
@@ -0,0 +1,12 @@
|
||||
import os
|
||||
|
||||
Import("globalEnv")
|
||||
|
||||
env = globalEnv.Clone()
|
||||
|
||||
env.Append(CPPPATH=[env["INIHCPPSRC"], env["INIHSRC"]])
|
||||
|
||||
files = Glob(os.path.join(env["INIHCPPSRC"], "*.cpp"))
|
||||
files.append(Glob(os.path.join(env["INIHSRC"], "*.c")))
|
||||
|
||||
env.Library(target="inihcpp", source=files)
|
1
contrib/iniParser/inih
Submodule
1
contrib/iniParser/inih
Submodule
Submodule contrib/iniParser/inih added at 2023872dff
24
contrib/minisat/SConscript
Normal file
24
contrib/minisat/SConscript
Normal file
@@ -0,0 +1,24 @@
|
||||
import os
|
||||
|
||||
Import("globalEnv")
|
||||
|
||||
env = globalEnv.Clone()
|
||||
|
||||
env.Append(CPPPATH=[env["MINISATSRC"]])
|
||||
|
||||
files = Glob(os.path.join(
|
||||
os.path.join(env["MINISATSRC"],
|
||||
"core"),
|
||||
"*.cc"))
|
||||
|
||||
files.append(Glob(os.path.join(
|
||||
os.path.join(env["MINISATSRC"],
|
||||
"simp"),
|
||||
"*.cc")))
|
||||
|
||||
files.append(Glob(os.path.join(
|
||||
os.path.join(env["MINISATSRC"],
|
||||
"util"),
|
||||
"*.cc")))
|
||||
|
||||
env.Library(target="minisat", source=files)
|
21
contrib/minisat/src/LICENSE
Normal file
21
contrib/minisat/src/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010 Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
contrib/minisat/src/README
Normal file
24
contrib/minisat/src/README
Normal file
@@ -0,0 +1,24 @@
|
||||
================================================================================
|
||||
DIRECTORY OVERVIEW:
|
||||
|
||||
mtl/ Mini Template Library
|
||||
utils/ Generic helper code (I/O, Parsing, CPU-time, etc)
|
||||
core/ A core version of the solver
|
||||
simp/ An extended solver with simplification capabilities
|
||||
README
|
||||
LICENSE
|
||||
|
||||
================================================================================
|
||||
BUILDING: (release version: without assertions, statically linked, etc)
|
||||
|
||||
export MROOT=<minisat-dir> (or setenv in cshell)
|
||||
cd { core | simp }
|
||||
gmake rs
|
||||
cp minisat_static <install-dir>/minisat
|
||||
|
||||
================================================================================
|
||||
EXAMPLES:
|
||||
|
||||
Run minisat with same heuristics as version 2.0:
|
||||
|
||||
> minisat <cnf-file> -no-luby -rinc=1.5 -phase-saving=0 -rnd-freq=0.02
|
89
contrib/minisat/src/core/Dimacs.h
Normal file
89
contrib/minisat/src/core/Dimacs.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************************[Dimacs.h]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Dimacs_h
|
||||
#define Minisat_Dimacs_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "utils/ParseUtils.h"
|
||||
#include "core/SolverTypes.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// DIMACS Parser:
|
||||
|
||||
template<class B, class Solver>
|
||||
static void readClause(B& in, Solver& S, vec<Lit>& lits) {
|
||||
int parsed_lit, var;
|
||||
lits.clear();
|
||||
for (;;){
|
||||
parsed_lit = parseInt(in);
|
||||
if (parsed_lit == 0) break;
|
||||
var = abs(parsed_lit)-1;
|
||||
while (var >= S.nVars()) S.newVar();
|
||||
lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) );
|
||||
}
|
||||
}
|
||||
|
||||
template<class B, class Solver>
|
||||
static void parse_DIMACS_main(B& in, Solver& S) {
|
||||
vec<Lit> lits;
|
||||
int vars = 0;
|
||||
int clauses = 0;
|
||||
int cnt = 0;
|
||||
for (;;){
|
||||
skipWhitespace(in);
|
||||
if (*in == EOF) break;
|
||||
else if (*in == 'p'){
|
||||
if (eagerMatch(in, "p cnf")){
|
||||
vars = parseInt(in);
|
||||
clauses = parseInt(in);
|
||||
// SATRACE'06 hack
|
||||
// if (clauses > 4000000)
|
||||
// S.eliminate(true);
|
||||
}else{
|
||||
printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
|
||||
}
|
||||
} else if (*in == 'c' || *in == 'p')
|
||||
skipLine(in);
|
||||
else{
|
||||
cnt++;
|
||||
readClause(in, S, lits);
|
||||
S.addClause_(lits); }
|
||||
}
|
||||
if (vars != S.nVars())
|
||||
fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of variables.\n");
|
||||
if (cnt != clauses)
|
||||
fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of clauses.\n");
|
||||
}
|
||||
|
||||
// Inserts problem into solver.
|
||||
//
|
||||
template<class Solver>
|
||||
static void parse_DIMACS(gzFile input_stream, Solver& S) {
|
||||
StreamBuffer in(input_stream);
|
||||
parse_DIMACS_main(in, S); }
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
192
contrib/minisat/src/core/Main.cc
Normal file
192
contrib/minisat/src/core/Main.cc
Normal file
@@ -0,0 +1,192 @@
|
||||
/*****************************************************************************************[Main.cc]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "utils/System.h"
|
||||
#include "utils/ParseUtils.h"
|
||||
#include "utils/Options.h"
|
||||
#include "core/Dimacs.h"
|
||||
#include "core/Solver.h"
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
|
||||
void printStats(Solver& solver)
|
||||
{
|
||||
double cpu_time = cpuTime();
|
||||
double mem_used = memUsedPeak();
|
||||
printf("restarts : %"PRIu64"\n", solver.starts);
|
||||
printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", solver.conflicts , solver.conflicts /cpu_time);
|
||||
printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions /cpu_time);
|
||||
printf("propagations : %-12"PRIu64" (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time);
|
||||
printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals);
|
||||
if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used);
|
||||
printf("CPU time : %g s\n", cpu_time);
|
||||
}
|
||||
|
||||
|
||||
static Solver* solver;
|
||||
// Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case
|
||||
// for this feature of the Solver as it may take longer than an immediate call to '_exit()'.
|
||||
static void SIGINT_interrupt(int signum) { solver->interrupt(); }
|
||||
|
||||
// Note that '_exit()' rather than 'exit()' has to be used. The reason is that 'exit()' calls
|
||||
// destructors and may cause deadlocks if a malloc/free function happens to be running (these
|
||||
// functions are guarded by locks for multithreaded use).
|
||||
static void SIGINT_exit(int signum) {
|
||||
printf("\n"); printf("*** INTERRUPTED ***\n");
|
||||
if (solver->verbosity > 0){
|
||||
printStats(*solver);
|
||||
printf("\n"); printf("*** INTERRUPTED ***\n"); }
|
||||
_exit(1); }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Main:
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try {
|
||||
setUsageHelp("USAGE: %s [options] <input-file> <result-output-file>\n\n where input may be either in plain or gzipped DIMACS.\n");
|
||||
// printf("This is MiniSat 2.0 beta\n");
|
||||
|
||||
#if defined(__linux__)
|
||||
fpu_control_t oldcw, newcw;
|
||||
_FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
|
||||
printf("WARNING: for repeatability, setting FPU to use double precision\n");
|
||||
#endif
|
||||
// Extra options:
|
||||
//
|
||||
IntOption verb ("MAIN", "verb", "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2));
|
||||
IntOption cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX));
|
||||
IntOption mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX));
|
||||
|
||||
parseOptions(argc, argv, true);
|
||||
|
||||
Solver S;
|
||||
double initial_time = cpuTime();
|
||||
|
||||
S.verbosity = verb;
|
||||
|
||||
solver = &S;
|
||||
// Use signal handlers that forcibly quit until the solver will be able to respond to
|
||||
// interrupts:
|
||||
signal(SIGINT, SIGINT_exit);
|
||||
signal(SIGXCPU,SIGINT_exit);
|
||||
|
||||
// Set limit on CPU-time:
|
||||
if (cpu_lim != INT32_MAX){
|
||||
rlimit rl;
|
||||
getrlimit(RLIMIT_CPU, &rl);
|
||||
if (rl.rlim_max == RLIM_INFINITY || (rlim_t)cpu_lim < rl.rlim_max){
|
||||
rl.rlim_cur = cpu_lim;
|
||||
if (setrlimit(RLIMIT_CPU, &rl) == -1)
|
||||
printf("WARNING! Could not set resource limit: CPU-time.\n");
|
||||
} }
|
||||
|
||||
// Set limit on virtual memory:
|
||||
if (mem_lim != INT32_MAX){
|
||||
rlim_t new_mem_lim = (rlim_t)mem_lim * 1024*1024;
|
||||
rlimit rl;
|
||||
getrlimit(RLIMIT_AS, &rl);
|
||||
if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){
|
||||
rl.rlim_cur = new_mem_lim;
|
||||
if (setrlimit(RLIMIT_AS, &rl) == -1)
|
||||
printf("WARNING! Could not set resource limit: Virtual memory.\n");
|
||||
} }
|
||||
|
||||
if (argc == 1)
|
||||
printf("Reading from standard input... Use '--help' for help.\n");
|
||||
|
||||
gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
|
||||
if (in == NULL)
|
||||
printf("ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]), exit(1);
|
||||
|
||||
if (S.verbosity > 0){
|
||||
printf("============================[ Problem Statistics ]=============================\n");
|
||||
printf("| |\n"); }
|
||||
|
||||
parse_DIMACS(in, S);
|
||||
gzclose(in);
|
||||
FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;
|
||||
|
||||
if (S.verbosity > 0){
|
||||
printf("| Number of variables: %12d |\n", S.nVars());
|
||||
printf("| Number of clauses: %12d |\n", S.nClauses()); }
|
||||
|
||||
double parsed_time = cpuTime();
|
||||
if (S.verbosity > 0){
|
||||
printf("| Parse time: %12.2f s |\n", parsed_time - initial_time);
|
||||
printf("| |\n"); }
|
||||
|
||||
// Change to signal-handlers that will only notify the solver and allow it to terminate
|
||||
// voluntarily:
|
||||
signal(SIGINT, SIGINT_interrupt);
|
||||
signal(SIGXCPU,SIGINT_interrupt);
|
||||
|
||||
if (!S.simplify()){
|
||||
if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res);
|
||||
if (S.verbosity > 0){
|
||||
printf("===============================================================================\n");
|
||||
printf("Solved by unit propagation\n");
|
||||
printStats(S);
|
||||
printf("\n"); }
|
||||
printf("UNSATISFIABLE\n");
|
||||
exit(20);
|
||||
}
|
||||
|
||||
vec<Lit> dummy;
|
||||
lbool ret = S.solveLimited(dummy);
|
||||
if (S.verbosity > 0){
|
||||
printStats(S);
|
||||
printf("\n"); }
|
||||
printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n");
|
||||
if (res != NULL){
|
||||
if (ret == l_True){
|
||||
fprintf(res, "SAT\n");
|
||||
for (int i = 0; i < S.nVars(); i++)
|
||||
if (S.model[i] != l_Undef)
|
||||
fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1);
|
||||
fprintf(res, " 0\n");
|
||||
}else if (ret == l_False)
|
||||
fprintf(res, "UNSAT\n");
|
||||
else
|
||||
fprintf(res, "INDET\n");
|
||||
fclose(res);
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
exit(ret == l_True ? 10 : ret == l_False ? 20 : 0); // (faster than "return", which will invoke the destructor for 'Solver')
|
||||
#else
|
||||
return (ret == l_True ? 10 : ret == l_False ? 20 : 0);
|
||||
#endif
|
||||
} catch (OutOfMemoryException&){
|
||||
printf("===============================================================================\n");
|
||||
printf("INDETERMINATE\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
4
contrib/minisat/src/core/Makefile
Normal file
4
contrib/minisat/src/core/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
EXEC = minisat
|
||||
DEPDIR = mtl utils
|
||||
|
||||
include $(MROOT)/mtl/template.mk
|
923
contrib/minisat/src/core/Solver.cc
Normal file
923
contrib/minisat/src/core/Solver.cc
Normal file
@@ -0,0 +1,923 @@
|
||||
/***************************************************************************************[Solver.cc]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "mtl/Sort.h"
|
||||
#include "core/Solver.h"
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
//=================================================================================================
|
||||
// Options:
|
||||
|
||||
|
||||
static const char* _cat = "CORE";
|
||||
|
||||
static DoubleOption opt_var_decay (_cat, "var-decay", "The variable activity decay factor", 0.95, DoubleRange(0, false, 1, false));
|
||||
static DoubleOption opt_clause_decay (_cat, "cla-decay", "The clause activity decay factor", 0.999, DoubleRange(0, false, 1, false));
|
||||
static DoubleOption opt_random_var_freq (_cat, "rnd-freq", "The frequency with which the decision heuristic tries to choose a random variable", 0, DoubleRange(0, true, 1, true));
|
||||
static DoubleOption opt_random_seed (_cat, "rnd-seed", "Used by the random variable selection", 91648253, DoubleRange(0, false, HUGE_VAL, false));
|
||||
static IntOption opt_ccmin_mode (_cat, "ccmin-mode", "Controls conflict clause minimization (0=none, 1=basic, 2=deep)", 2, IntRange(0, 2));
|
||||
static IntOption opt_phase_saving (_cat, "phase-saving", "Controls the level of phase saving (0=none, 1=limited, 2=full)", 2, IntRange(0, 2));
|
||||
static BoolOption opt_rnd_init_act (_cat, "rnd-init", "Randomize the initial activity", false);
|
||||
static BoolOption opt_luby_restart (_cat, "luby", "Use the Luby restart sequence", true);
|
||||
static IntOption opt_restart_first (_cat, "rfirst", "The base restart interval", 100, IntRange(1, INT32_MAX));
|
||||
static DoubleOption opt_restart_inc (_cat, "rinc", "Restart interval increase factor", 2, DoubleRange(1, false, HUGE_VAL, false));
|
||||
static DoubleOption opt_garbage_frac (_cat, "gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered", 0.20, DoubleRange(0, false, HUGE_VAL, false));
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Constructor/Destructor:
|
||||
|
||||
|
||||
Solver::Solver() :
|
||||
|
||||
// Parameters (user settable):
|
||||
//
|
||||
verbosity (0)
|
||||
, var_decay (opt_var_decay)
|
||||
, clause_decay (opt_clause_decay)
|
||||
, random_var_freq (opt_random_var_freq)
|
||||
, random_seed (opt_random_seed)
|
||||
, luby_restart (opt_luby_restart)
|
||||
, ccmin_mode (opt_ccmin_mode)
|
||||
, phase_saving (opt_phase_saving)
|
||||
, rnd_pol (false)
|
||||
, rnd_init_act (opt_rnd_init_act)
|
||||
, garbage_frac (opt_garbage_frac)
|
||||
, restart_first (opt_restart_first)
|
||||
, restart_inc (opt_restart_inc)
|
||||
|
||||
// Parameters (the rest):
|
||||
//
|
||||
, learntsize_factor((double)1/(double)3), learntsize_inc(1.1)
|
||||
|
||||
// Parameters (experimental):
|
||||
//
|
||||
, learntsize_adjust_start_confl (100)
|
||||
, learntsize_adjust_inc (1.5)
|
||||
|
||||
// Statistics: (formerly in 'SolverStats')
|
||||
//
|
||||
, solves(0), starts(0), decisions(0), rnd_decisions(0), propagations(0), conflicts(0)
|
||||
, dec_vars(0), clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0)
|
||||
|
||||
, ok (true)
|
||||
, cla_inc (1)
|
||||
, var_inc (1)
|
||||
, watches (WatcherDeleted(ca))
|
||||
, qhead (0)
|
||||
, simpDB_assigns (-1)
|
||||
, simpDB_props (0)
|
||||
, order_heap (VarOrderLt(activity))
|
||||
, progress_estimate (0)
|
||||
, remove_satisfied (true)
|
||||
|
||||
// Resource constraints:
|
||||
//
|
||||
, conflict_budget (-1)
|
||||
, propagation_budget (-1)
|
||||
, asynch_interrupt (false)
|
||||
{}
|
||||
|
||||
|
||||
Solver::~Solver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Minor methods:
|
||||
|
||||
|
||||
// Creates a new SAT variable in the solver. If 'decision' is cleared, variable will not be
|
||||
// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
|
||||
//
|
||||
Var Solver::newVar(bool sign, bool dvar)
|
||||
{
|
||||
int v = nVars();
|
||||
watches .init(mkLit(v, false));
|
||||
watches .init(mkLit(v, true ));
|
||||
assigns .push(l_Undef);
|
||||
vardata .push(mkVarData(CRef_Undef, 0));
|
||||
//activity .push(0);
|
||||
activity .push(rnd_init_act ? drand(random_seed) * 0.00001 : 0);
|
||||
seen .push(0);
|
||||
polarity .push(sign);
|
||||
decision .push();
|
||||
trail .capacity(v+1);
|
||||
setDecisionVar(v, dvar);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
bool Solver::addClause_(vec<Lit>& ps)
|
||||
{
|
||||
assert(decisionLevel() == 0);
|
||||
if (!ok) return false;
|
||||
|
||||
// Check if clause is satisfied and remove false/duplicate literals:
|
||||
sort(ps);
|
||||
Lit p; int i, j;
|
||||
for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
|
||||
if (value(ps[i]) == l_True || ps[i] == ~p)
|
||||
return true;
|
||||
else if (value(ps[i]) != l_False && ps[i] != p)
|
||||
ps[j++] = p = ps[i];
|
||||
ps.shrink(i - j);
|
||||
|
||||
if (ps.size() == 0)
|
||||
return ok = false;
|
||||
else if (ps.size() == 1){
|
||||
uncheckedEnqueue(ps[0]);
|
||||
return ok = (propagate() == CRef_Undef);
|
||||
}else{
|
||||
CRef cr = ca.alloc(ps, false);
|
||||
clauses.push(cr);
|
||||
attachClause(cr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Solver::attachClause(CRef cr) {
|
||||
const Clause& c = ca[cr];
|
||||
assert(c.size() > 1);
|
||||
watches[~c[0]].push(Watcher(cr, c[1]));
|
||||
watches[~c[1]].push(Watcher(cr, c[0]));
|
||||
if (c.learnt()) learnts_literals += c.size();
|
||||
else clauses_literals += c.size(); }
|
||||
|
||||
|
||||
void Solver::detachClause(CRef cr, bool strict) {
|
||||
const Clause& c = ca[cr];
|
||||
assert(c.size() > 1);
|
||||
|
||||
if (strict){
|
||||
remove(watches[~c[0]], Watcher(cr, c[1]));
|
||||
remove(watches[~c[1]], Watcher(cr, c[0]));
|
||||
}else{
|
||||
// Lazy detaching: (NOTE! Must clean all watcher lists before garbage collecting this clause)
|
||||
watches.smudge(~c[0]);
|
||||
watches.smudge(~c[1]);
|
||||
}
|
||||
|
||||
if (c.learnt()) learnts_literals -= c.size();
|
||||
else clauses_literals -= c.size(); }
|
||||
|
||||
|
||||
void Solver::removeClause(CRef cr) {
|
||||
Clause& c = ca[cr];
|
||||
detachClause(cr);
|
||||
// Don't leave pointers to free'd memory!
|
||||
if (locked(c)) vardata[var(c[0])].reason = CRef_Undef;
|
||||
c.mark(1);
|
||||
ca.free(cr);
|
||||
}
|
||||
|
||||
|
||||
bool Solver::satisfied(const Clause& c) const {
|
||||
for (int i = 0; i < c.size(); i++)
|
||||
if (value(c[i]) == l_True)
|
||||
return true;
|
||||
return false; }
|
||||
|
||||
|
||||
// Revert to the state at given level (keeping all assignment at 'level' but not beyond).
|
||||
//
|
||||
void Solver::cancelUntil(int level) {
|
||||
if (decisionLevel() > level){
|
||||
for (int c = trail.size()-1; c >= trail_lim[level]; c--){
|
||||
Var x = var(trail[c]);
|
||||
assigns [x] = l_Undef;
|
||||
if (phase_saving > 1 || (phase_saving == 1) && c > trail_lim.last())
|
||||
polarity[x] = sign(trail[c]);
|
||||
insertVarOrder(x); }
|
||||
qhead = trail_lim[level];
|
||||
trail.shrink(trail.size() - trail_lim[level]);
|
||||
trail_lim.shrink(trail_lim.size() - level);
|
||||
} }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Major methods:
|
||||
|
||||
|
||||
Lit Solver::pickBranchLit()
|
||||
{
|
||||
Var next = var_Undef;
|
||||
|
||||
// Random decision:
|
||||
if (drand(random_seed) < random_var_freq && !order_heap.empty()){
|
||||
next = order_heap[irand(random_seed,order_heap.size())];
|
||||
if (value(next) == l_Undef && decision[next])
|
||||
rnd_decisions++; }
|
||||
|
||||
// Activity based decision:
|
||||
while (next == var_Undef || value(next) != l_Undef || !decision[next])
|
||||
if (order_heap.empty()){
|
||||
next = var_Undef;
|
||||
break;
|
||||
}else
|
||||
next = order_heap.removeMin();
|
||||
|
||||
return next == var_Undef ? lit_Undef : mkLit(next, rnd_pol ? drand(random_seed) < 0.5 : polarity[next]);
|
||||
}
|
||||
|
||||
|
||||
/*_________________________________________________________________________________________________
|
||||
|
|
||||
| analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void]
|
||||
|
|
||||
| Description:
|
||||
| Analyze conflict and produce a reason clause.
|
||||
|
|
||||
| Pre-conditions:
|
||||
| * 'out_learnt' is assumed to be cleared.
|
||||
| * Current decision level must be greater than root level.
|
||||
|
|
||||
| Post-conditions:
|
||||
| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
|
||||
| * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the
|
||||
| rest of literals. There may be others from the same level though.
|
||||
|
|
||||
|________________________________________________________________________________________________@*/
|
||||
void Solver::analyze(CRef confl, vec<Lit>& out_learnt, int& out_btlevel)
|
||||
{
|
||||
int pathC = 0;
|
||||
Lit p = lit_Undef;
|
||||
|
||||
// Generate conflict clause:
|
||||
//
|
||||
out_learnt.push(); // (leave room for the asserting literal)
|
||||
int index = trail.size() - 1;
|
||||
|
||||
do{
|
||||
assert(confl != CRef_Undef); // (otherwise should be UIP)
|
||||
Clause& c = ca[confl];
|
||||
|
||||
if (c.learnt())
|
||||
claBumpActivity(c);
|
||||
|
||||
for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
|
||||
Lit q = c[j];
|
||||
|
||||
if (!seen[var(q)] && level(var(q)) > 0){
|
||||
varBumpActivity(var(q));
|
||||
seen[var(q)] = 1;
|
||||
if (level(var(q)) >= decisionLevel())
|
||||
pathC++;
|
||||
else
|
||||
out_learnt.push(q);
|
||||
}
|
||||
}
|
||||
|
||||
// Select next clause to look at:
|
||||
while (!seen[var(trail[index--])]);
|
||||
p = trail[index+1];
|
||||
confl = reason(var(p));
|
||||
seen[var(p)] = 0;
|
||||
pathC--;
|
||||
|
||||
}while (pathC > 0);
|
||||
out_learnt[0] = ~p;
|
||||
|
||||
// Simplify conflict clause:
|
||||
//
|
||||
int i, j;
|
||||
out_learnt.copyTo(analyze_toclear);
|
||||
if (ccmin_mode == 2){
|
||||
uint32_t abstract_level = 0;
|
||||
for (i = 1; i < out_learnt.size(); i++)
|
||||
abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict)
|
||||
|
||||
for (i = j = 1; i < out_learnt.size(); i++)
|
||||
if (reason(var(out_learnt[i])) == CRef_Undef || !litRedundant(out_learnt[i], abstract_level))
|
||||
out_learnt[j++] = out_learnt[i];
|
||||
|
||||
}else if (ccmin_mode == 1){
|
||||
for (i = j = 1; i < out_learnt.size(); i++){
|
||||
Var x = var(out_learnt[i]);
|
||||
|
||||
if (reason(x) == CRef_Undef)
|
||||
out_learnt[j++] = out_learnt[i];
|
||||
else{
|
||||
Clause& c = ca[reason(var(out_learnt[i]))];
|
||||
for (int k = 1; k < c.size(); k++)
|
||||
if (!seen[var(c[k])] && level(var(c[k])) > 0){
|
||||
out_learnt[j++] = out_learnt[i];
|
||||
break; }
|
||||
}
|
||||
}
|
||||
}else
|
||||
i = j = out_learnt.size();
|
||||
|
||||
max_literals += out_learnt.size();
|
||||
out_learnt.shrink(i - j);
|
||||
tot_literals += out_learnt.size();
|
||||
|
||||
// Find correct backtrack level:
|
||||
//
|
||||
if (out_learnt.size() == 1)
|
||||
out_btlevel = 0;
|
||||
else{
|
||||
int max_i = 1;
|
||||
// Find the first literal assigned at the next-highest level:
|
||||
for (int i = 2; i < out_learnt.size(); i++)
|
||||
if (level(var(out_learnt[i])) > level(var(out_learnt[max_i])))
|
||||
max_i = i;
|
||||
// Swap-in this literal at index 1:
|
||||
Lit p = out_learnt[max_i];
|
||||
out_learnt[max_i] = out_learnt[1];
|
||||
out_learnt[1] = p;
|
||||
out_btlevel = level(var(p));
|
||||
}
|
||||
|
||||
for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared)
|
||||
}
|
||||
|
||||
|
||||
// Check if 'p' can be removed. 'abstract_levels' is used to abort early if the algorithm is
|
||||
// visiting literals at levels that cannot be removed later.
|
||||
bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
|
||||
{
|
||||
analyze_stack.clear(); analyze_stack.push(p);
|
||||
int top = analyze_toclear.size();
|
||||
while (analyze_stack.size() > 0){
|
||||
assert(reason(var(analyze_stack.last())) != CRef_Undef);
|
||||
Clause& c = ca[reason(var(analyze_stack.last()))]; analyze_stack.pop();
|
||||
|
||||
for (int i = 1; i < c.size(); i++){
|
||||
Lit p = c[i];
|
||||
if (!seen[var(p)] && level(var(p)) > 0){
|
||||
if (reason(var(p)) != CRef_Undef && (abstractLevel(var(p)) & abstract_levels) != 0){
|
||||
seen[var(p)] = 1;
|
||||
analyze_stack.push(p);
|
||||
analyze_toclear.push(p);
|
||||
}else{
|
||||
for (int j = top; j < analyze_toclear.size(); j++)
|
||||
seen[var(analyze_toclear[j])] = 0;
|
||||
analyze_toclear.shrink(analyze_toclear.size() - top);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*_________________________________________________________________________________________________
|
||||
|
|
||||
| analyzeFinal : (p : Lit) -> [void]
|
||||
|
|
||||
| Description:
|
||||
| Specialized analysis procedure to express the final conflict in terms of assumptions.
|
||||
| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
|
||||
| stores the result in 'out_conflict'.
|
||||
|________________________________________________________________________________________________@*/
|
||||
void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
|
||||
{
|
||||
out_conflict.clear();
|
||||
out_conflict.push(p);
|
||||
|
||||
if (decisionLevel() == 0)
|
||||
return;
|
||||
|
||||
seen[var(p)] = 1;
|
||||
|
||||
for (int i = trail.size()-1; i >= trail_lim[0]; i--){
|
||||
Var x = var(trail[i]);
|
||||
if (seen[x]){
|
||||
if (reason(x) == CRef_Undef){
|
||||
assert(level(x) > 0);
|
||||
out_conflict.push(~trail[i]);
|
||||
}else{
|
||||
Clause& c = ca[reason(x)];
|
||||
for (int j = 1; j < c.size(); j++)
|
||||
if (level(var(c[j])) > 0)
|
||||
seen[var(c[j])] = 1;
|
||||
}
|
||||
seen[x] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
seen[var(p)] = 0;
|
||||
}
|
||||
|
||||
|
||||
void Solver::uncheckedEnqueue(Lit p, CRef from)
|
||||
{
|
||||
assert(value(p) == l_Undef);
|
||||
assigns[var(p)] = lbool(!sign(p));
|
||||
vardata[var(p)] = mkVarData(from, decisionLevel());
|
||||
trail.push_(p);
|
||||
}
|
||||
|
||||
|
||||
/*_________________________________________________________________________________________________
|
||||
|
|
||||
| propagate : [void] -> [Clause*]
|
||||
|
|
||||
| Description:
|
||||
| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
|
||||
| otherwise CRef_Undef.
|
||||
|
|
||||
| Post-conditions:
|
||||
| * the propagation queue is empty, even if there was a conflict.
|
||||
|________________________________________________________________________________________________@*/
|
||||
CRef Solver::propagate()
|
||||
{
|
||||
CRef confl = CRef_Undef;
|
||||
int num_props = 0;
|
||||
watches.cleanAll();
|
||||
|
||||
while (qhead < trail.size()){
|
||||
Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate.
|
||||
vec<Watcher>& ws = watches[p];
|
||||
Watcher *i, *j, *end;
|
||||
num_props++;
|
||||
|
||||
for (i = j = (Watcher*)ws, end = i + ws.size(); i != end;){
|
||||
// Try to avoid inspecting the clause:
|
||||
Lit blocker = i->blocker;
|
||||
if (value(blocker) == l_True){
|
||||
*j++ = *i++; continue; }
|
||||
|
||||
// Make sure the false literal is data[1]:
|
||||
CRef cr = i->cref;
|
||||
Clause& c = ca[cr];
|
||||
Lit false_lit = ~p;
|
||||
if (c[0] == false_lit)
|
||||
c[0] = c[1], c[1] = false_lit;
|
||||
assert(c[1] == false_lit);
|
||||
i++;
|
||||
|
||||
// If 0th watch is true, then clause is already satisfied.
|
||||
Lit first = c[0];
|
||||
Watcher w = Watcher(cr, first);
|
||||
if (first != blocker && value(first) == l_True){
|
||||
*j++ = w; continue; }
|
||||
|
||||
// Look for new watch:
|
||||
for (int k = 2; k < c.size(); k++)
|
||||
if (value(c[k]) != l_False){
|
||||
c[1] = c[k]; c[k] = false_lit;
|
||||
watches[~c[1]].push(w);
|
||||
goto NextClause; }
|
||||
|
||||
// Did not find watch -- clause is unit under assignment:
|
||||
*j++ = w;
|
||||
if (value(first) == l_False){
|
||||
confl = cr;
|
||||
qhead = trail.size();
|
||||
// Copy the remaining watches:
|
||||
while (i < end)
|
||||
*j++ = *i++;
|
||||
}else
|
||||
uncheckedEnqueue(first, cr);
|
||||
|
||||
NextClause:;
|
||||
}
|
||||
ws.shrink(i - j);
|
||||
}
|
||||
propagations += num_props;
|
||||
simpDB_props -= num_props;
|
||||
|
||||
return confl;
|
||||
}
|
||||
|
||||
|
||||
/*_________________________________________________________________________________________________
|
||||
|
|
||||
| reduceDB : () -> [void]
|
||||
|
|
||||
| Description:
|
||||
| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked
|
||||
| clauses are clauses that are reason to some assignment. Binary clauses are never removed.
|
||||
|________________________________________________________________________________________________@*/
|
||||
struct reduceDB_lt {
|
||||
ClauseAllocator& ca;
|
||||
reduceDB_lt(ClauseAllocator& ca_) : ca(ca_) {}
|
||||
bool operator () (CRef x, CRef y) {
|
||||
return ca[x].size() > 2 && (ca[y].size() == 2 || ca[x].activity() < ca[y].activity()); }
|
||||
};
|
||||
void Solver::reduceDB()
|
||||
{
|
||||
int i, j;
|
||||
double extra_lim = cla_inc / learnts.size(); // Remove any clause below this activity
|
||||
|
||||
sort(learnts, reduceDB_lt(ca));
|
||||
// Don't delete binary or locked clauses. From the rest, delete clauses from the first half
|
||||
// and clauses with activity smaller than 'extra_lim':
|
||||
for (i = j = 0; i < learnts.size(); i++){
|
||||
Clause& c = ca[learnts[i]];
|
||||
if (c.size() > 2 && !locked(c) && (i < learnts.size() / 2 || c.activity() < extra_lim))
|
||||
removeClause(learnts[i]);
|
||||
else
|
||||
learnts[j++] = learnts[i];
|
||||
}
|
||||
learnts.shrink(i - j);
|
||||
checkGarbage();
|
||||
}
|
||||
|
||||
|
||||
void Solver::removeSatisfied(vec<CRef>& cs)
|
||||
{
|
||||
int i, j;
|
||||
for (i = j = 0; i < cs.size(); i++){
|
||||
Clause& c = ca[cs[i]];
|
||||
if (satisfied(c))
|
||||
removeClause(cs[i]);
|
||||
else
|
||||
cs[j++] = cs[i];
|
||||
}
|
||||
cs.shrink(i - j);
|
||||
}
|
||||
|
||||
|
||||
void Solver::rebuildOrderHeap()
|
||||
{
|
||||
vec<Var> vs;
|
||||
for (Var v = 0; v < nVars(); v++)
|
||||
if (decision[v] && value(v) == l_Undef)
|
||||
vs.push(v);
|
||||
order_heap.build(vs);
|
||||
}
|
||||
|
||||
|
||||
/*_________________________________________________________________________________________________
|
||||
|
|
||||
| simplify : [void] -> [bool]
|
||||
|
|
||||
| Description:
|
||||
| Simplify the clause database according to the current top-level assigment. Currently, the only
|
||||
| thing done here is the removal of satisfied clauses, but more things can be put here.
|
||||
|________________________________________________________________________________________________@*/
|
||||
bool Solver::simplify()
|
||||
{
|
||||
assert(decisionLevel() == 0);
|
||||
|
||||
if (!ok || propagate() != CRef_Undef)
|
||||
return ok = false;
|
||||
|
||||
if (nAssigns() == simpDB_assigns || (simpDB_props > 0))
|
||||
return true;
|
||||
|
||||
// Remove satisfied clauses:
|
||||
removeSatisfied(learnts);
|
||||
if (remove_satisfied) // Can be turned off.
|
||||
removeSatisfied(clauses);
|
||||
checkGarbage();
|
||||
rebuildOrderHeap();
|
||||
|
||||
simpDB_assigns = nAssigns();
|
||||
simpDB_props = clauses_literals + learnts_literals; // (shouldn't depend on stats really, but it will do for now)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*_________________________________________________________________________________________________
|
||||
|
|
||||
| search : (nof_conflicts : int) (params : const SearchParams&) -> [lbool]
|
||||
|
|
||||
| Description:
|
||||
| Search for a model the specified number of conflicts.
|
||||
| NOTE! Use negative value for 'nof_conflicts' indicate infinity.
|
||||
|
|
||||
| Output:
|
||||
| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
|
||||
| all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
|
||||
| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
|
||||
|________________________________________________________________________________________________@*/
|
||||
lbool Solver::search(int nof_conflicts)
|
||||
{
|
||||
assert(ok);
|
||||
int backtrack_level;
|
||||
int conflictC = 0;
|
||||
vec<Lit> learnt_clause;
|
||||
starts++;
|
||||
|
||||
for (;;){
|
||||
CRef confl = propagate();
|
||||
if (confl != CRef_Undef){
|
||||
// CONFLICT
|
||||
conflicts++; conflictC++;
|
||||
if (decisionLevel() == 0) return l_False;
|
||||
|
||||
learnt_clause.clear();
|
||||
analyze(confl, learnt_clause, backtrack_level);
|
||||
cancelUntil(backtrack_level);
|
||||
|
||||
if (learnt_clause.size() == 1){
|
||||
uncheckedEnqueue(learnt_clause[0]);
|
||||
}else{
|
||||
CRef cr = ca.alloc(learnt_clause, true);
|
||||
learnts.push(cr);
|
||||
attachClause(cr);
|
||||
claBumpActivity(ca[cr]);
|
||||
uncheckedEnqueue(learnt_clause[0], cr);
|
||||
}
|
||||
|
||||
varDecayActivity();
|
||||
claDecayActivity();
|
||||
|
||||
if (--learntsize_adjust_cnt == 0){
|
||||
learntsize_adjust_confl *= learntsize_adjust_inc;
|
||||
learntsize_adjust_cnt = (int)learntsize_adjust_confl;
|
||||
max_learnts *= learntsize_inc;
|
||||
|
||||
if (verbosity >= 1)
|
||||
printf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n",
|
||||
(int)conflicts,
|
||||
(int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals,
|
||||
(int)max_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progressEstimate()*100);
|
||||
}
|
||||
|
||||
}else{
|
||||
// NO CONFLICT
|
||||
if (nof_conflicts >= 0 && conflictC >= nof_conflicts || !withinBudget()){
|
||||
// Reached bound on number of conflicts:
|
||||
progress_estimate = progressEstimate();
|
||||
cancelUntil(0);
|
||||
return l_Undef; }
|
||||
|
||||
// Simplify the set of problem clauses:
|
||||
if (decisionLevel() == 0 && !simplify())
|
||||
return l_False;
|
||||
|
||||
if (learnts.size()-nAssigns() >= max_learnts)
|
||||
// Reduce the set of learnt clauses:
|
||||
reduceDB();
|
||||
|
||||
Lit next = lit_Undef;
|
||||
while (decisionLevel() < assumptions.size()){
|
||||
// Perform user provided assumption:
|
||||
Lit p = assumptions[decisionLevel()];
|
||||
if (value(p) == l_True){
|
||||
// Dummy decision level:
|
||||
newDecisionLevel();
|
||||
}else if (value(p) == l_False){
|
||||
analyzeFinal(~p, conflict);
|
||||
return l_False;
|
||||
}else{
|
||||
next = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (next == lit_Undef){
|
||||
// New variable decision:
|
||||
decisions++;
|
||||
next = pickBranchLit();
|
||||
|
||||
if (next == lit_Undef)
|
||||
// Model found:
|
||||
return l_True;
|
||||
}
|
||||
|
||||
// Increase decision level and enqueue 'next'
|
||||
newDecisionLevel();
|
||||
uncheckedEnqueue(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double Solver::progressEstimate() const
|
||||
{
|
||||
double progress = 0;
|
||||
double F = 1.0 / nVars();
|
||||
|
||||
for (int i = 0; i <= decisionLevel(); i++){
|
||||
int beg = i == 0 ? 0 : trail_lim[i - 1];
|
||||
int end = i == decisionLevel() ? trail.size() : trail_lim[i];
|
||||
progress += pow(F, i) * (end - beg);
|
||||
}
|
||||
|
||||
return progress / nVars();
|
||||
}
|
||||
|
||||
/*
|
||||
Finite subsequences of the Luby-sequence:
|
||||
|
||||
0: 1
|
||||
1: 1 1 2
|
||||
2: 1 1 2 1 1 2 4
|
||||
3: 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8
|
||||
...
|
||||
|
||||
|
||||
*/
|
||||
|
||||
static double luby(double y, int x){
|
||||
|
||||
// Find the finite subsequence that contains index 'x', and the
|
||||
// size of that subsequence:
|
||||
int size, seq;
|
||||
for (size = 1, seq = 0; size < x+1; seq++, size = 2*size+1);
|
||||
|
||||
while (size-1 != x){
|
||||
size = (size-1)>>1;
|
||||
seq--;
|
||||
x = x % size;
|
||||
}
|
||||
|
||||
return pow(y, seq);
|
||||
}
|
||||
|
||||
// NOTE: assumptions passed in member-variable 'assumptions'.
|
||||
lbool Solver::solve_()
|
||||
{
|
||||
model.clear();
|
||||
conflict.clear();
|
||||
if (!ok) return l_False;
|
||||
|
||||
solves++;
|
||||
|
||||
max_learnts = nClauses() * learntsize_factor;
|
||||
learntsize_adjust_confl = learntsize_adjust_start_confl;
|
||||
learntsize_adjust_cnt = (int)learntsize_adjust_confl;
|
||||
lbool status = l_Undef;
|
||||
|
||||
if (verbosity >= 1){
|
||||
printf("============================[ Search Statistics ]==============================\n");
|
||||
printf("| Conflicts | ORIGINAL | LEARNT | Progress |\n");
|
||||
printf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n");
|
||||
printf("===============================================================================\n");
|
||||
}
|
||||
|
||||
// Search:
|
||||
int curr_restarts = 0;
|
||||
while (status == l_Undef){
|
||||
double rest_base = luby_restart ? luby(restart_inc, curr_restarts) : pow(restart_inc, curr_restarts);
|
||||
status = search(rest_base * restart_first);
|
||||
if (!withinBudget()) break;
|
||||
curr_restarts++;
|
||||
}
|
||||
|
||||
if (verbosity >= 1)
|
||||
printf("===============================================================================\n");
|
||||
|
||||
|
||||
if (status == l_True){
|
||||
// Extend & copy model:
|
||||
model.growTo(nVars());
|
||||
for (int i = 0; i < nVars(); i++) model[i] = value(i);
|
||||
}else if (status == l_False && conflict.size() == 0)
|
||||
ok = false;
|
||||
|
||||
cancelUntil(0);
|
||||
return status;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
// Writing CNF to DIMACS:
|
||||
//
|
||||
// FIXME: this needs to be rewritten completely.
|
||||
|
||||
static Var mapVar(Var x, vec<Var>& map, Var& max)
|
||||
{
|
||||
if (map.size() <= x || map[x] == -1){
|
||||
map.growTo(x+1, -1);
|
||||
map[x] = max++;
|
||||
}
|
||||
return map[x];
|
||||
}
|
||||
|
||||
|
||||
void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
|
||||
{
|
||||
if (satisfied(c)) return;
|
||||
|
||||
for (int i = 0; i < c.size(); i++)
|
||||
if (value(c[i]) != l_False)
|
||||
fprintf(f, "%s%d ", sign(c[i]) ? "-" : "", mapVar(var(c[i]), map, max)+1);
|
||||
fprintf(f, "0\n");
|
||||
}
|
||||
|
||||
|
||||
void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
|
||||
{
|
||||
FILE* f = fopen(file, "wr");
|
||||
if (f == NULL)
|
||||
fprintf(stderr, "could not open file %s\n", file), exit(1);
|
||||
toDimacs(f, assumps);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
void Solver::toDimacs(FILE* f, const vec<Lit>& assumps)
|
||||
{
|
||||
// Handle case when solver is in contradictory state:
|
||||
if (!ok){
|
||||
fprintf(f, "p cnf 1 2\n1 0\n-1 0\n");
|
||||
return; }
|
||||
|
||||
vec<Var> map; Var max = 0;
|
||||
|
||||
// Cannot use removeClauses here because it is not safe
|
||||
// to deallocate them at this point. Could be improved.
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < clauses.size(); i++)
|
||||
if (!satisfied(ca[clauses[i]]))
|
||||
cnt++;
|
||||
|
||||
for (int i = 0; i < clauses.size(); i++)
|
||||
if (!satisfied(ca[clauses[i]])){
|
||||
Clause& c = ca[clauses[i]];
|
||||
for (int j = 0; j < c.size(); j++)
|
||||
if (value(c[j]) != l_False)
|
||||
mapVar(var(c[j]), map, max);
|
||||
}
|
||||
|
||||
// Assumptions are added as unit clauses:
|
||||
cnt += assumptions.size();
|
||||
|
||||
fprintf(f, "p cnf %d %d\n", max, cnt);
|
||||
|
||||
for (int i = 0; i < assumptions.size(); i++){
|
||||
assert(value(assumptions[i]) != l_False);
|
||||
fprintf(f, "%s%d 0\n", sign(assumptions[i]) ? "-" : "", mapVar(var(assumptions[i]), map, max)+1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < clauses.size(); i++)
|
||||
toDimacs(f, ca[clauses[i]], map, max);
|
||||
|
||||
if (verbosity > 0)
|
||||
printf("Wrote %d clauses with %d variables.\n", cnt, max);
|
||||
}
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Garbage Collection methods:
|
||||
|
||||
void Solver::relocAll(ClauseAllocator& to)
|
||||
{
|
||||
// All watchers:
|
||||
//
|
||||
// for (int i = 0; i < watches.size(); i++)
|
||||
watches.cleanAll();
|
||||
for (int v = 0; v < nVars(); v++)
|
||||
for (int s = 0; s < 2; s++){
|
||||
Lit p = mkLit(v, s);
|
||||
// printf(" >>> RELOCING: %s%d\n", sign(p)?"-":"", var(p)+1);
|
||||
vec<Watcher>& ws = watches[p];
|
||||
for (int j = 0; j < ws.size(); j++)
|
||||
ca.reloc(ws[j].cref, to);
|
||||
}
|
||||
|
||||
// All reasons:
|
||||
//
|
||||
for (int i = 0; i < trail.size(); i++){
|
||||
Var v = var(trail[i]);
|
||||
|
||||
if (reason(v) != CRef_Undef && (ca[reason(v)].reloced() || locked(ca[reason(v)])))
|
||||
ca.reloc(vardata[v].reason, to);
|
||||
}
|
||||
|
||||
// All learnt:
|
||||
//
|
||||
for (int i = 0; i < learnts.size(); i++)
|
||||
ca.reloc(learnts[i], to);
|
||||
|
||||
// All original:
|
||||
//
|
||||
for (int i = 0; i < clauses.size(); i++)
|
||||
ca.reloc(clauses[i], to);
|
||||
}
|
||||
|
||||
|
||||
void Solver::garbageCollect()
|
||||
{
|
||||
// Initialize the next region to a size corresponding to the estimated utilization degree. This
|
||||
// is not precise but should avoid some unnecessary reallocations for the new region:
|
||||
ClauseAllocator to(ca.size() - ca.wasted());
|
||||
|
||||
relocAll(to);
|
||||
if (verbosity >= 2)
|
||||
printf("| Garbage collection: %12d bytes => %12d bytes |\n",
|
||||
ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
|
||||
to.moveTo(ca);
|
||||
}
|
373
contrib/minisat/src/core/Solver.h
Normal file
373
contrib/minisat/src/core/Solver.h
Normal file
@@ -0,0 +1,373 @@
|
||||
/****************************************************************************************[Solver.h]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Solver_h
|
||||
#define Minisat_Solver_h
|
||||
|
||||
#include "mtl/Vec.h"
|
||||
#include "mtl/Heap.h"
|
||||
#include "mtl/Alg.h"
|
||||
#include "utils/Options.h"
|
||||
#include "core/SolverTypes.h"
|
||||
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// Solver -- the main class:
|
||||
|
||||
class Solver {
|
||||
public:
|
||||
|
||||
// Constructor/Destructor:
|
||||
//
|
||||
Solver();
|
||||
virtual ~Solver();
|
||||
|
||||
// Problem specification:
|
||||
//
|
||||
Var newVar (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode.
|
||||
|
||||
bool addClause (const vec<Lit>& ps); // Add a clause to the solver.
|
||||
bool addEmptyClause(); // Add the empty clause, making the solver contradictory.
|
||||
bool addClause (Lit p); // Add a unit clause to the solver.
|
||||
bool addClause (Lit p, Lit q); // Add a binary clause to the solver.
|
||||
bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
|
||||
bool addClause_( vec<Lit>& ps); // Add a clause to the solver without making superflous internal copy. Will
|
||||
// change the passed vector 'ps'.
|
||||
|
||||
// Solving:
|
||||
//
|
||||
bool simplify (); // Removes already satisfied clauses.
|
||||
bool solve (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions.
|
||||
lbool solveLimited (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions (With resource constraints).
|
||||
bool solve (); // Search without assumptions.
|
||||
bool solve (Lit p); // Search for a model that respects a single assumption.
|
||||
bool solve (Lit p, Lit q); // Search for a model that respects two assumptions.
|
||||
bool solve (Lit p, Lit q, Lit r); // Search for a model that respects three assumptions.
|
||||
bool okay () const; // FALSE means solver is in a conflicting state
|
||||
|
||||
void toDimacs (FILE* f, const vec<Lit>& assumps); // Write CNF to file in DIMACS-format.
|
||||
void toDimacs (const char *file, const vec<Lit>& assumps);
|
||||
void toDimacs (FILE* f, Clause& c, vec<Var>& map, Var& max);
|
||||
|
||||
// Convenience versions of 'toDimacs()':
|
||||
void toDimacs (const char* file);
|
||||
void toDimacs (const char* file, Lit p);
|
||||
void toDimacs (const char* file, Lit p, Lit q);
|
||||
void toDimacs (const char* file, Lit p, Lit q, Lit r);
|
||||
|
||||
// Variable mode:
|
||||
//
|
||||
void setPolarity (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'.
|
||||
void setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic.
|
||||
|
||||
// Read state:
|
||||
//
|
||||
lbool value (Var x) const; // The current value of a variable.
|
||||
lbool value (Lit p) const; // The current value of a literal.
|
||||
lbool modelValue (Var x) const; // The value of a variable in the last model. The last call to solve must have been satisfiable.
|
||||
lbool modelValue (Lit p) const; // The value of a literal in the last model. The last call to solve must have been satisfiable.
|
||||
int nAssigns () const; // The current number of assigned literals.
|
||||
int nClauses () const; // The current number of original clauses.
|
||||
int nLearnts () const; // The current number of learnt clauses.
|
||||
int nVars () const; // The current number of variables.
|
||||
int nFreeVars () const;
|
||||
|
||||
// Resource contraints:
|
||||
//
|
||||
void setConfBudget(int64_t x);
|
||||
void setPropBudget(int64_t x);
|
||||
void budgetOff();
|
||||
void interrupt(); // Trigger a (potentially asynchronous) interruption of the solver.
|
||||
void clearInterrupt(); // Clear interrupt indicator flag.
|
||||
|
||||
// Memory managment:
|
||||
//
|
||||
virtual void garbageCollect();
|
||||
void checkGarbage(double gf);
|
||||
void checkGarbage();
|
||||
|
||||
// Extra results: (read-only member variable)
|
||||
//
|
||||
vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any).
|
||||
vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions),
|
||||
// this vector represent the final conflict clause expressed in the assumptions.
|
||||
|
||||
// Mode of operation:
|
||||
//
|
||||
int verbosity;
|
||||
double var_decay;
|
||||
double clause_decay;
|
||||
double random_var_freq;
|
||||
double random_seed;
|
||||
bool luby_restart;
|
||||
int ccmin_mode; // Controls conflict clause minimization (0=none, 1=basic, 2=deep).
|
||||
int phase_saving; // Controls the level of phase saving (0=none, 1=limited, 2=full).
|
||||
bool rnd_pol; // Use random polarities for branching heuristics.
|
||||
bool rnd_init_act; // Initialize variable activities with a small random value.
|
||||
double garbage_frac; // The fraction of wasted memory allowed before a garbage collection is triggered.
|
||||
|
||||
int restart_first; // The initial restart limit. (default 100)
|
||||
double restart_inc; // The factor with which the restart limit is multiplied in each restart. (default 1.5)
|
||||
double learntsize_factor; // The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3)
|
||||
double learntsize_inc; // The limit for learnt clauses is multiplied with this factor each restart. (default 1.1)
|
||||
|
||||
int learntsize_adjust_start_confl;
|
||||
double learntsize_adjust_inc;
|
||||
|
||||
// Statistics: (read-only member variable)
|
||||
//
|
||||
uint64_t solves, starts, decisions, rnd_decisions, propagations, conflicts;
|
||||
uint64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals;
|
||||
|
||||
protected:
|
||||
|
||||
// Helper structures:
|
||||
//
|
||||
struct VarData { CRef reason; int level; };
|
||||
static inline VarData mkVarData(CRef cr, int l){ VarData d = {cr, l}; return d; }
|
||||
|
||||
struct Watcher {
|
||||
CRef cref;
|
||||
Lit blocker;
|
||||
Watcher(CRef cr, Lit p) : cref(cr), blocker(p) {}
|
||||
bool operator==(const Watcher& w) const { return cref == w.cref; }
|
||||
bool operator!=(const Watcher& w) const { return cref != w.cref; }
|
||||
};
|
||||
|
||||
struct WatcherDeleted
|
||||
{
|
||||
const ClauseAllocator& ca;
|
||||
WatcherDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
|
||||
bool operator()(const Watcher& w) const { return ca[w.cref].mark() == 1; }
|
||||
};
|
||||
|
||||
struct VarOrderLt {
|
||||
const vec<double>& activity;
|
||||
bool operator () (Var x, Var y) const { return activity[x] > activity[y]; }
|
||||
VarOrderLt(const vec<double>& act) : activity(act) { }
|
||||
};
|
||||
|
||||
// Solver state:
|
||||
//
|
||||
bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
|
||||
vec<CRef> clauses; // List of problem clauses.
|
||||
vec<CRef> learnts; // List of learnt clauses.
|
||||
double cla_inc; // Amount to bump next clause with.
|
||||
vec<double> activity; // A heuristic measurement of the activity of a variable.
|
||||
double var_inc; // Amount to bump next variable with.
|
||||
OccLists<Lit, vec<Watcher>, WatcherDeleted>
|
||||
watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
|
||||
vec<lbool> assigns; // The current assignments.
|
||||
vec<char> polarity; // The preferred polarity of each variable.
|
||||
vec<char> decision; // Declares if a variable is eligible for selection in the decision heuristic.
|
||||
vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
|
||||
vec<int> trail_lim; // Separator indices for different decision levels in 'trail'.
|
||||
vec<VarData> vardata; // Stores reason and level for each variable.
|
||||
int qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
|
||||
int simpDB_assigns; // Number of top-level assignments since last execution of 'simplify()'.
|
||||
int64_t simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplify()'.
|
||||
vec<Lit> assumptions; // Current set of assumptions provided to solve by the user.
|
||||
Heap<VarOrderLt> order_heap; // A priority queue of variables ordered with respect to the variable activity.
|
||||
double progress_estimate;// Set by 'search()'.
|
||||
bool remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'.
|
||||
|
||||
ClauseAllocator ca;
|
||||
|
||||
// Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
|
||||
// used, exept 'seen' wich is used in several places.
|
||||
//
|
||||
vec<char> seen;
|
||||
vec<Lit> analyze_stack;
|
||||
vec<Lit> analyze_toclear;
|
||||
vec<Lit> add_tmp;
|
||||
|
||||
double max_learnts;
|
||||
double learntsize_adjust_confl;
|
||||
int learntsize_adjust_cnt;
|
||||
|
||||
// Resource contraints:
|
||||
//
|
||||
int64_t conflict_budget; // -1 means no budget.
|
||||
int64_t propagation_budget; // -1 means no budget.
|
||||
bool asynch_interrupt;
|
||||
|
||||
// Main internal methods:
|
||||
//
|
||||
void insertVarOrder (Var x); // Insert a variable in the decision order priority queue.
|
||||
Lit pickBranchLit (); // Return the next decision variable.
|
||||
void newDecisionLevel (); // Begins a new decision level.
|
||||
void uncheckedEnqueue (Lit p, CRef from = CRef_Undef); // Enqueue a literal. Assumes value of literal is undefined.
|
||||
bool enqueue (Lit p, CRef from = CRef_Undef); // Test if fact 'p' contradicts current state, enqueue otherwise.
|
||||
CRef propagate (); // Perform unit propagation. Returns possibly conflicting clause.
|
||||
void cancelUntil (int level); // Backtrack until a certain level.
|
||||
void analyze (CRef confl, vec<Lit>& out_learnt, int& out_btlevel); // (bt = backtrack)
|
||||
void analyzeFinal (Lit p, vec<Lit>& out_conflict); // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION?
|
||||
bool litRedundant (Lit p, uint32_t abstract_levels); // (helper method for 'analyze()')
|
||||
lbool search (int nof_conflicts); // Search for a given number of conflicts.
|
||||
lbool solve_ (); // Main solve method (assumptions given in 'assumptions').
|
||||
void reduceDB (); // Reduce the set of learnt clauses.
|
||||
void removeSatisfied (vec<CRef>& cs); // Shrink 'cs' to contain only non-satisfied clauses.
|
||||
void rebuildOrderHeap ();
|
||||
|
||||
// Maintaining Variable/Clause activity:
|
||||
//
|
||||
void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead.
|
||||
void varBumpActivity (Var v, double inc); // Increase a variable with the current 'bump' value.
|
||||
void varBumpActivity (Var v); // Increase a variable with the current 'bump' value.
|
||||
void claDecayActivity (); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead.
|
||||
void claBumpActivity (Clause& c); // Increase a clause with the current 'bump' value.
|
||||
|
||||
// Operations on clauses:
|
||||
//
|
||||
void attachClause (CRef cr); // Attach a clause to watcher lists.
|
||||
void detachClause (CRef cr, bool strict = false); // Detach a clause to watcher lists.
|
||||
void removeClause (CRef cr); // Detach and free a clause.
|
||||
bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state.
|
||||
bool satisfied (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state.
|
||||
|
||||
void relocAll (ClauseAllocator& to);
|
||||
|
||||
// Misc:
|
||||
//
|
||||
int decisionLevel () const; // Gives the current decisionlevel.
|
||||
uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels.
|
||||
CRef reason (Var x) const;
|
||||
int level (Var x) const;
|
||||
double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
|
||||
bool withinBudget () const;
|
||||
|
||||
// Static helpers:
|
||||
//
|
||||
|
||||
// Returns a random float 0 <= x < 1. Seed must never be 0.
|
||||
static inline double drand(double& seed) {
|
||||
seed *= 1389796;
|
||||
int q = (int)(seed / 2147483647);
|
||||
seed -= (double)q * 2147483647;
|
||||
return seed / 2147483647; }
|
||||
|
||||
// Returns a random integer 0 <= x < size. Seed must never be 0.
|
||||
static inline int irand(double& seed, int size) {
|
||||
return (int)(drand(seed) * size); }
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Implementation of inline methods:
|
||||
|
||||
inline CRef Solver::reason(Var x) const { return vardata[x].reason; }
|
||||
inline int Solver::level (Var x) const { return vardata[x].level; }
|
||||
|
||||
inline void Solver::insertVarOrder(Var x) {
|
||||
if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x); }
|
||||
|
||||
inline void Solver::varDecayActivity() { var_inc *= (1 / var_decay); }
|
||||
inline void Solver::varBumpActivity(Var v) { varBumpActivity(v, var_inc); }
|
||||
inline void Solver::varBumpActivity(Var v, double inc) {
|
||||
if ( (activity[v] += inc) > 1e100 ) {
|
||||
// Rescale:
|
||||
for (int i = 0; i < nVars(); i++)
|
||||
activity[i] *= 1e-100;
|
||||
var_inc *= 1e-100; }
|
||||
|
||||
// Update order_heap with respect to new activity:
|
||||
if (order_heap.inHeap(v))
|
||||
order_heap.decrease(v); }
|
||||
|
||||
inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); }
|
||||
inline void Solver::claBumpActivity (Clause& c) {
|
||||
if ( (c.activity() += cla_inc) > 1e20 ) {
|
||||
// Rescale:
|
||||
for (int i = 0; i < learnts.size(); i++)
|
||||
ca[learnts[i]].activity() *= 1e-20;
|
||||
cla_inc *= 1e-20; } }
|
||||
|
||||
inline void Solver::checkGarbage(void){ return checkGarbage(garbage_frac); }
|
||||
inline void Solver::checkGarbage(double gf){
|
||||
if (ca.wasted() > ca.size() * gf)
|
||||
garbageCollect(); }
|
||||
|
||||
// NOTE: enqueue does not set the ok flag! (only public methods do)
|
||||
inline bool Solver::enqueue (Lit p, CRef from) { return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true); }
|
||||
inline bool Solver::addClause (const vec<Lit>& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); }
|
||||
inline bool Solver::addEmptyClause () { add_tmp.clear(); return addClause_(add_tmp); }
|
||||
inline bool Solver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
|
||||
inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
|
||||
inline bool Solver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
|
||||
inline bool Solver::locked (const Clause& c) const { return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c; }
|
||||
inline void Solver::newDecisionLevel() { trail_lim.push(trail.size()); }
|
||||
|
||||
inline int Solver::decisionLevel () const { return trail_lim.size(); }
|
||||
inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); }
|
||||
inline lbool Solver::value (Var x) const { return assigns[x]; }
|
||||
inline lbool Solver::value (Lit p) const { return assigns[var(p)] ^ sign(p); }
|
||||
inline lbool Solver::modelValue (Var x) const { return model[x]; }
|
||||
inline lbool Solver::modelValue (Lit p) const { return model[var(p)] ^ sign(p); }
|
||||
inline int Solver::nAssigns () const { return trail.size(); }
|
||||
inline int Solver::nClauses () const { return clauses.size(); }
|
||||
inline int Solver::nLearnts () const { return learnts.size(); }
|
||||
inline int Solver::nVars () const { return vardata.size(); }
|
||||
inline int Solver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); }
|
||||
inline void Solver::setPolarity (Var v, bool b) { polarity[v] = b; }
|
||||
inline void Solver::setDecisionVar(Var v, bool b)
|
||||
{
|
||||
if ( b && !decision[v]) dec_vars++;
|
||||
else if (!b && decision[v]) dec_vars--;
|
||||
|
||||
decision[v] = b;
|
||||
insertVarOrder(v);
|
||||
}
|
||||
inline void Solver::setConfBudget(int64_t x){ conflict_budget = conflicts + x; }
|
||||
inline void Solver::setPropBudget(int64_t x){ propagation_budget = propagations + x; }
|
||||
inline void Solver::interrupt(){ asynch_interrupt = true; }
|
||||
inline void Solver::clearInterrupt(){ asynch_interrupt = false; }
|
||||
inline void Solver::budgetOff(){ conflict_budget = propagation_budget = -1; }
|
||||
inline bool Solver::withinBudget() const {
|
||||
return !asynch_interrupt &&
|
||||
(conflict_budget < 0 || conflicts < (uint64_t)conflict_budget) &&
|
||||
(propagation_budget < 0 || propagations < (uint64_t)propagation_budget); }
|
||||
|
||||
// FIXME: after the introduction of asynchronous interrruptions the solve-versions that return a
|
||||
// pure bool do not give a safe interface. Either interrupts must be possible to turn off here, or
|
||||
// all calls to solve must return an 'lbool'. I'm not yet sure which I prefer.
|
||||
inline bool Solver::solve () { budgetOff(); assumptions.clear(); return solve_() == l_True; }
|
||||
inline bool Solver::solve (Lit p) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_() == l_True; }
|
||||
inline bool Solver::solve (Lit p, Lit q) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_() == l_True; }
|
||||
inline bool Solver::solve (Lit p, Lit q, Lit r) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_() == l_True; }
|
||||
inline bool Solver::solve (const vec<Lit>& assumps){ budgetOff(); assumps.copyTo(assumptions); return solve_() == l_True; }
|
||||
inline lbool Solver::solveLimited (const vec<Lit>& assumps){ assumps.copyTo(assumptions); return solve_(); }
|
||||
inline bool Solver::okay () const { return ok; }
|
||||
|
||||
inline void Solver::toDimacs (const char* file){ vec<Lit> as; toDimacs(file, as); }
|
||||
inline void Solver::toDimacs (const char* file, Lit p){ vec<Lit> as; as.push(p); toDimacs(file, as); }
|
||||
inline void Solver::toDimacs (const char* file, Lit p, Lit q){ vec<Lit> as; as.push(p); as.push(q); toDimacs(file, as); }
|
||||
inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ vec<Lit> as; as.push(p); as.push(q); as.push(r); toDimacs(file, as); }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Debug etc:
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
407
contrib/minisat/src/core/SolverTypes.h
Normal file
407
contrib/minisat/src/core/SolverTypes.h
Normal file
@@ -0,0 +1,407 @@
|
||||
/***********************************************************************************[SolverTypes.h]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
|
||||
#ifndef Minisat_SolverTypes_h
|
||||
#define Minisat_SolverTypes_h
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "mtl/IntTypes.h"
|
||||
#include "mtl/Alg.h"
|
||||
#include "mtl/Vec.h"
|
||||
#include "mtl/Map.h"
|
||||
#include "mtl/Alloc.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// Variables, literals, lifted booleans, clauses:
|
||||
|
||||
|
||||
// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
|
||||
// so that they can be used as array indices.
|
||||
|
||||
typedef int Var;
|
||||
#define var_Undef (-1)
|
||||
|
||||
|
||||
struct Lit {
|
||||
int x;
|
||||
|
||||
// Use this as a constructor:
|
||||
friend Lit mkLit(Var var, bool sign = false);
|
||||
|
||||
bool operator == (Lit p) const { return x == p.x; }
|
||||
bool operator != (Lit p) const { return x != p.x; }
|
||||
bool operator < (Lit p) const { return x < p.x; } // '<' makes p, ~p adjacent in the ordering.
|
||||
};
|
||||
|
||||
|
||||
inline Lit mkLit (Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; }
|
||||
inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; }
|
||||
inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; }
|
||||
inline bool sign (Lit p) { return p.x & 1; }
|
||||
inline int var (Lit p) { return p.x >> 1; }
|
||||
|
||||
// Mapping Literals to and from compact integers suitable for array indexing:
|
||||
inline int toInt (Var v) { return v; }
|
||||
inline int toInt (Lit p) { return p.x; }
|
||||
inline Lit toLit (int i) { Lit p; p.x = i; return p; }
|
||||
|
||||
//const Lit lit_Undef = mkLit(var_Undef, false); // }- Useful special constants.
|
||||
//const Lit lit_Error = mkLit(var_Undef, true ); // }
|
||||
|
||||
const Lit lit_Undef = { -2 }; // }- Useful special constants.
|
||||
const Lit lit_Error = { -1 }; // }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Lifted booleans:
|
||||
//
|
||||
// NOTE: this implementation is optimized for the case when comparisons between values are mostly
|
||||
// between one variable and one constant. Some care had to be taken to make sure that gcc
|
||||
// does enough constant propagation to produce sensible code, and this appears to be somewhat
|
||||
// fragile unfortunately.
|
||||
|
||||
#define l_True (lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants.
|
||||
#define l_False (lbool((uint8_t)1))
|
||||
#define l_Undef (lbool((uint8_t)2))
|
||||
|
||||
class lbool {
|
||||
uint8_t value;
|
||||
|
||||
public:
|
||||
explicit lbool(uint8_t v) : value(v) { }
|
||||
|
||||
lbool() : value(0) { }
|
||||
explicit lbool(bool x) : value(!x) { }
|
||||
|
||||
bool operator == (lbool b) const { return ((b.value&2) & (value&2)) | (!(b.value&2)&(value == b.value)); }
|
||||
bool operator != (lbool b) const { return !(*this == b); }
|
||||
lbool operator ^ (bool b) const { return lbool((uint8_t)(value^(uint8_t)b)); }
|
||||
|
||||
lbool operator && (lbool b) const {
|
||||
uint8_t sel = (this->value << 1) | (b.value << 3);
|
||||
uint8_t v = (0xF7F755F4 >> sel) & 3;
|
||||
return lbool(v); }
|
||||
|
||||
lbool operator || (lbool b) const {
|
||||
uint8_t sel = (this->value << 1) | (b.value << 3);
|
||||
uint8_t v = (0xFCFCF400 >> sel) & 3;
|
||||
return lbool(v); }
|
||||
|
||||
friend int toInt (lbool l);
|
||||
friend lbool toLbool(int v);
|
||||
};
|
||||
inline int toInt (lbool l) { return l.value; }
|
||||
inline lbool toLbool(int v) { return lbool((uint8_t)v); }
|
||||
|
||||
//=================================================================================================
|
||||
// Clause -- a simple class for representing a clause:
|
||||
|
||||
class Clause;
|
||||
typedef RegionAllocator<uint32_t>::Ref CRef;
|
||||
|
||||
class Clause {
|
||||
struct {
|
||||
unsigned mark : 2;
|
||||
unsigned learnt : 1;
|
||||
unsigned has_extra : 1;
|
||||
unsigned reloced : 1;
|
||||
unsigned size : 27; } header;
|
||||
union { Lit lit; float act; uint32_t abs; CRef rel; } data[0];
|
||||
|
||||
friend class ClauseAllocator;
|
||||
|
||||
// NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
|
||||
template<class V>
|
||||
Clause(const V& ps, bool use_extra, bool learnt) {
|
||||
header.mark = 0;
|
||||
header.learnt = learnt;
|
||||
header.has_extra = use_extra;
|
||||
header.reloced = 0;
|
||||
header.size = ps.size();
|
||||
|
||||
for (int i = 0; i < ps.size(); i++)
|
||||
data[i].lit = ps[i];
|
||||
|
||||
if (header.has_extra){
|
||||
if (header.learnt)
|
||||
data[header.size].act = 0;
|
||||
else
|
||||
calcAbstraction(); }
|
||||
}
|
||||
|
||||
public:
|
||||
void calcAbstraction() {
|
||||
assert(header.has_extra);
|
||||
uint32_t abstraction = 0;
|
||||
for (int i = 0; i < size(); i++)
|
||||
abstraction |= 1 << (var(data[i].lit) & 31);
|
||||
data[header.size].abs = abstraction; }
|
||||
|
||||
|
||||
int size () const { return header.size; }
|
||||
void shrink (int i) { assert(i <= size()); if (header.has_extra) data[header.size-i] = data[header.size]; header.size -= i; }
|
||||
void pop () { shrink(1); }
|
||||
bool learnt () const { return header.learnt; }
|
||||
bool has_extra () const { return header.has_extra; }
|
||||
uint32_t mark () const { return header.mark; }
|
||||
void mark (uint32_t m) { header.mark = m; }
|
||||
const Lit& last () const { return data[header.size-1].lit; }
|
||||
|
||||
bool reloced () const { return header.reloced; }
|
||||
CRef relocation () const { return data[0].rel; }
|
||||
void relocate (CRef c) { header.reloced = 1; data[0].rel = c; }
|
||||
|
||||
// NOTE: somewhat unsafe to change the clause in-place! Must manually call 'calcAbstraction' afterwards for
|
||||
// subsumption operations to behave correctly.
|
||||
Lit& operator [] (int i) { return data[i].lit; }
|
||||
Lit operator [] (int i) const { return data[i].lit; }
|
||||
operator const Lit* (void) const { return (Lit*)data; }
|
||||
|
||||
float& activity () { assert(header.has_extra); return data[header.size].act; }
|
||||
uint32_t abstraction () const { assert(header.has_extra); return data[header.size].abs; }
|
||||
|
||||
Lit subsumes (const Clause& other) const;
|
||||
void strengthen (Lit p);
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// ClauseAllocator -- a simple class for allocating memory for clauses:
|
||||
|
||||
|
||||
const CRef CRef_Undef = RegionAllocator<uint32_t>::Ref_Undef;
|
||||
class ClauseAllocator : public RegionAllocator<uint32_t>
|
||||
{
|
||||
static int clauseWord32Size(int size, bool has_extra){
|
||||
return (sizeof(Clause) + (sizeof(Lit) * (size + (int)has_extra))) / sizeof(uint32_t); }
|
||||
public:
|
||||
bool extra_clause_field;
|
||||
|
||||
ClauseAllocator(uint32_t start_cap) : RegionAllocator<uint32_t>(start_cap), extra_clause_field(false){}
|
||||
ClauseAllocator() : extra_clause_field(false){}
|
||||
|
||||
void moveTo(ClauseAllocator& to){
|
||||
to.extra_clause_field = extra_clause_field;
|
||||
RegionAllocator<uint32_t>::moveTo(to); }
|
||||
|
||||
template<class Lits>
|
||||
CRef alloc(const Lits& ps, bool learnt = false)
|
||||
{
|
||||
assert(sizeof(Lit) == sizeof(uint32_t));
|
||||
assert(sizeof(float) == sizeof(uint32_t));
|
||||
bool use_extra = learnt | extra_clause_field;
|
||||
|
||||
CRef cid = RegionAllocator<uint32_t>::alloc(clauseWord32Size(ps.size(), use_extra));
|
||||
new (lea(cid)) Clause(ps, use_extra, learnt);
|
||||
|
||||
return cid;
|
||||
}
|
||||
|
||||
// Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
|
||||
Clause& operator[](Ref r) { return (Clause&)RegionAllocator<uint32_t>::operator[](r); }
|
||||
const Clause& operator[](Ref r) const { return (Clause&)RegionAllocator<uint32_t>::operator[](r); }
|
||||
Clause* lea (Ref r) { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
|
||||
const Clause* lea (Ref r) const { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
|
||||
Ref ael (const Clause* t){ return RegionAllocator<uint32_t>::ael((uint32_t*)t); }
|
||||
|
||||
void free(CRef cid)
|
||||
{
|
||||
Clause& c = operator[](cid);
|
||||
RegionAllocator<uint32_t>::free(clauseWord32Size(c.size(), c.has_extra()));
|
||||
}
|
||||
|
||||
void reloc(CRef& cr, ClauseAllocator& to)
|
||||
{
|
||||
Clause& c = operator[](cr);
|
||||
|
||||
if (c.reloced()) { cr = c.relocation(); return; }
|
||||
|
||||
cr = to.alloc(c, c.learnt());
|
||||
c.relocate(cr);
|
||||
|
||||
// Copy extra data-fields:
|
||||
// (This could be cleaned-up. Generalize Clause-constructor to be applicable here instead?)
|
||||
to[cr].mark(c.mark());
|
||||
if (to[cr].learnt()) to[cr].activity() = c.activity();
|
||||
else if (to[cr].has_extra()) to[cr].calcAbstraction();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// OccLists -- a class for maintaining occurence lists with lazy deletion:
|
||||
|
||||
template<class Idx, class Vec, class Deleted>
|
||||
class OccLists
|
||||
{
|
||||
vec<Vec> occs;
|
||||
vec<char> dirty;
|
||||
vec<Idx> dirties;
|
||||
Deleted deleted;
|
||||
|
||||
public:
|
||||
OccLists(const Deleted& d) : deleted(d) {}
|
||||
|
||||
void init (const Idx& idx){ occs.growTo(toInt(idx)+1); dirty.growTo(toInt(idx)+1, 0); }
|
||||
// Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
|
||||
Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
|
||||
Vec& lookup (const Idx& idx){ if (dirty[toInt(idx)]) clean(idx); return occs[toInt(idx)]; }
|
||||
|
||||
void cleanAll ();
|
||||
void clean (const Idx& idx);
|
||||
void smudge (const Idx& idx){
|
||||
if (dirty[toInt(idx)] == 0){
|
||||
dirty[toInt(idx)] = 1;
|
||||
dirties.push(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void clear(bool free = true){
|
||||
occs .clear(free);
|
||||
dirty .clear(free);
|
||||
dirties.clear(free);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class Idx, class Vec, class Deleted>
|
||||
void OccLists<Idx,Vec,Deleted>::cleanAll()
|
||||
{
|
||||
for (int i = 0; i < dirties.size(); i++)
|
||||
// Dirties may contain duplicates so check here if a variable is already cleaned:
|
||||
if (dirty[toInt(dirties[i])])
|
||||
clean(dirties[i]);
|
||||
dirties.clear();
|
||||
}
|
||||
|
||||
|
||||
template<class Idx, class Vec, class Deleted>
|
||||
void OccLists<Idx,Vec,Deleted>::clean(const Idx& idx)
|
||||
{
|
||||
Vec& vec = occs[toInt(idx)];
|
||||
int i, j;
|
||||
for (i = j = 0; i < vec.size(); i++)
|
||||
if (!deleted(vec[i]))
|
||||
vec[j++] = vec[i];
|
||||
vec.shrink(i - j);
|
||||
dirty[toInt(idx)] = 0;
|
||||
}
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// CMap -- a class for mapping clauses to values:
|
||||
|
||||
|
||||
template<class T>
|
||||
class CMap
|
||||
{
|
||||
struct CRefHash {
|
||||
uint32_t operator()(CRef cr) const { return (uint32_t)cr; } };
|
||||
|
||||
typedef Map<CRef, T, CRefHash> HashTable;
|
||||
HashTable map;
|
||||
|
||||
public:
|
||||
// Size-operations:
|
||||
void clear () { map.clear(); }
|
||||
int size () const { return map.elems(); }
|
||||
|
||||
|
||||
// Insert/Remove/Test mapping:
|
||||
void insert (CRef cr, const T& t){ map.insert(cr, t); }
|
||||
void growTo (CRef cr, const T& t){ map.insert(cr, t); } // NOTE: for compatibility
|
||||
void remove (CRef cr) { map.remove(cr); }
|
||||
bool has (CRef cr, T& t) { return map.peek(cr, t); }
|
||||
|
||||
// Vector interface (the clause 'c' must already exist):
|
||||
const T& operator [] (CRef cr) const { return map[cr]; }
|
||||
T& operator [] (CRef cr) { return map[cr]; }
|
||||
|
||||
// Iteration (not transparent at all at the moment):
|
||||
int bucket_count() const { return map.bucket_count(); }
|
||||
const vec<typename HashTable::Pair>& bucket(int i) const { return map.bucket(i); }
|
||||
|
||||
// Move contents to other map:
|
||||
void moveTo(CMap& other){ map.moveTo(other.map); }
|
||||
|
||||
// TMP debug:
|
||||
void debug(){
|
||||
printf(" --- size = %d, bucket_count = %d\n", size(), map.bucket_count()); }
|
||||
};
|
||||
|
||||
|
||||
/*_________________________________________________________________________________________________
|
||||
|
|
||||
| subsumes : (other : const Clause&) -> Lit
|
||||
|
|
||||
| Description:
|
||||
| Checks if clause subsumes 'other', and at the same time, if it can be used to simplify 'other'
|
||||
| by subsumption resolution.
|
||||
|
|
||||
| Result:
|
||||
| lit_Error - No subsumption or simplification
|
||||
| lit_Undef - Clause subsumes 'other'
|
||||
| p - The literal p can be deleted from 'other'
|
||||
|________________________________________________________________________________________________@*/
|
||||
inline Lit Clause::subsumes(const Clause& other) const
|
||||
{
|
||||
//if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0)
|
||||
//if (other.size() < size() || (!learnt() && !other.learnt() && (extra.abst & ~other.extra.abst) != 0))
|
||||
assert(!header.learnt); assert(!other.header.learnt);
|
||||
assert(header.has_extra); assert(other.header.has_extra);
|
||||
if (other.header.size < header.size || (data[header.size].abs & ~other.data[other.header.size].abs) != 0)
|
||||
return lit_Error;
|
||||
|
||||
Lit ret = lit_Undef;
|
||||
const Lit* c = (const Lit*)(*this);
|
||||
const Lit* d = (const Lit*)other;
|
||||
|
||||
for (unsigned i = 0; i < header.size; i++) {
|
||||
// search for c[i] or ~c[i]
|
||||
for (unsigned j = 0; j < other.header.size; j++)
|
||||
if (c[i] == d[j])
|
||||
goto ok;
|
||||
else if (ret == lit_Undef && c[i] == ~d[j]){
|
||||
ret = c[i];
|
||||
goto ok;
|
||||
}
|
||||
|
||||
// did not find it
|
||||
return lit_Error;
|
||||
ok:;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void Clause::strengthen(Lit p)
|
||||
{
|
||||
remove(*this, p);
|
||||
calcAbstraction();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
79
contrib/minisat/src/doc/ReleaseNotes-2.2.0.txt
Normal file
79
contrib/minisat/src/doc/ReleaseNotes-2.2.0.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
Release Notes for MiniSat 2.2.0
|
||||
===============================
|
||||
|
||||
Changes since version 2.0:
|
||||
|
||||
* Started using a more standard release numbering.
|
||||
|
||||
* Includes some now well-known heuristics: phase-saving and luby
|
||||
restarts. The old heuristics are still present and can be activated
|
||||
if needed.
|
||||
|
||||
* Detection/Handling of out-of-memory and vector capacity
|
||||
overflow. This is fairly new and relatively untested.
|
||||
|
||||
* Simple resource controls: CPU-time, memory, number of
|
||||
conflicts/decisions.
|
||||
|
||||
* CPU-time limiting is implemented by a more general, but simple,
|
||||
asynchronous interruption feature. This means that the solving
|
||||
procedure can be interrupted from another thread or in a signal
|
||||
handler.
|
||||
|
||||
* Improved portability with respect to building on Solaris and with
|
||||
Visual Studio. This is not regularly tested and chances are that
|
||||
this have been broken since, but should be fairly easy to fix if
|
||||
so.
|
||||
|
||||
* Changed C++ file-extention to the less problematic ".cc".
|
||||
|
||||
* Source code is now namespace-protected
|
||||
|
||||
* Introducing a new Clause Memory Allocator that brings reduced
|
||||
memory consumption on 64-bit architechtures and improved
|
||||
performance (to some extent). The allocator uses a region-based
|
||||
approach were all references to clauses are represented as a 32-bit
|
||||
index into a global memory region that contains all clauses. To
|
||||
free up and compact memory it uses a simple copying garbage
|
||||
collector.
|
||||
|
||||
* Improved unit-propagation by Blocking Literals. For each entry in
|
||||
the watcher lists, pair the pointer to a clause with some
|
||||
(arbitrary) literal from the clause. The idea is that if the
|
||||
literal is currently true (i.e. the clause is satisfied) the
|
||||
watchers of the clause does not need to be altered. This can thus
|
||||
be detected without touching the clause's memory at all. As often
|
||||
as can be done cheaply, the blocking literal for entries to the
|
||||
watcher list of a literal 'p' is set to the other literal watched
|
||||
in the corresponding clause.
|
||||
|
||||
* Basic command-line/option handling system. Makes it easy to specify
|
||||
options in the class that they affect, and whenever that class is
|
||||
used in an executable, parsing of options and help messages are
|
||||
brought in automatically.
|
||||
|
||||
* General clean-up and various minor bug-fixes.
|
||||
|
||||
* Changed implementation of variable-elimination/model-extension:
|
||||
|
||||
- The interface is changed so that arbitrary remembering is no longer
|
||||
possible. If you need to mention some variable again in the future,
|
||||
this variable has to be frozen.
|
||||
|
||||
- When eliminating a variable, only clauses that contain the variable
|
||||
with one sign is necessary to store. Thereby making the other sign
|
||||
a "default" value when extending models.
|
||||
|
||||
- The memory consumption for eliminated clauses is further improved
|
||||
by storing all eliminated clauses in a single contiguous vector.
|
||||
|
||||
* Some common utility code (I/O, Parsing, CPU-time, etc) is ripped
|
||||
out and placed in a separate "utils" directory.
|
||||
|
||||
* The DIMACS parse is refactored so that it can be reused in other
|
||||
applications (not very elegant, but at least possible).
|
||||
|
||||
* Some simple improvements to scalability of preprocessing, using
|
||||
more lazy clause removal from data-structures and a couple of
|
||||
ad-hoc limits (the longest clause that can be produced in variable
|
||||
elimination, and the longest clause used in backward subsumption).
|
84
contrib/minisat/src/mtl/Alg.h
Normal file
84
contrib/minisat/src/mtl/Alg.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*******************************************************************************************[Alg.h]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Alg_h
|
||||
#define Minisat_Alg_h
|
||||
|
||||
#include "mtl/Vec.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// Useful functions on vector-like types:
|
||||
|
||||
//=================================================================================================
|
||||
// Removing and searching for elements:
|
||||
//
|
||||
|
||||
template<class V, class T>
|
||||
static inline void remove(V& ts, const T& t)
|
||||
{
|
||||
int j = 0;
|
||||
for (; j < ts.size() && ts[j] != t; j++);
|
||||
assert(j < ts.size());
|
||||
for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
|
||||
ts.pop();
|
||||
}
|
||||
|
||||
|
||||
template<class V, class T>
|
||||
static inline bool find(V& ts, const T& t)
|
||||
{
|
||||
int j = 0;
|
||||
for (; j < ts.size() && ts[j] != t; j++);
|
||||
return j < ts.size();
|
||||
}
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Copying vectors with support for nested vector types:
|
||||
//
|
||||
|
||||
// Base case:
|
||||
template<class T>
|
||||
static inline void copy(const T& from, T& to)
|
||||
{
|
||||
to = from;
|
||||
}
|
||||
|
||||
// Recursive case:
|
||||
template<class T>
|
||||
static inline void copy(const vec<T>& from, vec<T>& to, bool append = false)
|
||||
{
|
||||
if (!append)
|
||||
to.clear();
|
||||
for (int i = 0; i < from.size(); i++){
|
||||
to.push();
|
||||
copy(from[i], to.last());
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
static inline void append(const vec<T>& from, vec<T>& to){ copy(from, to, true); }
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
131
contrib/minisat/src/mtl/Alloc.h
Normal file
131
contrib/minisat/src/mtl/Alloc.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*****************************************************************************************[Alloc.h]
|
||||
Copyright (c) 2008-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
|
||||
#ifndef Minisat_Alloc_h
|
||||
#define Minisat_Alloc_h
|
||||
|
||||
#include "mtl/XAlloc.h"
|
||||
#include "mtl/Vec.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// Simple Region-based memory allocator:
|
||||
|
||||
template<class T>
|
||||
class RegionAllocator
|
||||
{
|
||||
T* memory;
|
||||
uint32_t sz;
|
||||
uint32_t cap;
|
||||
uint32_t wasted_;
|
||||
|
||||
void capacity(uint32_t min_cap);
|
||||
|
||||
public:
|
||||
// TODO: make this a class for better type-checking?
|
||||
typedef uint32_t Ref;
|
||||
enum { Ref_Undef = UINT32_MAX };
|
||||
enum { Unit_Size = sizeof(uint32_t) };
|
||||
|
||||
explicit RegionAllocator(uint32_t start_cap = 1024*1024) : memory(NULL), sz(0), cap(0), wasted_(0){ capacity(start_cap); }
|
||||
~RegionAllocator()
|
||||
{
|
||||
if (memory != NULL)
|
||||
::free(memory);
|
||||
}
|
||||
|
||||
|
||||
uint32_t size () const { return sz; }
|
||||
uint32_t wasted () const { return wasted_; }
|
||||
|
||||
Ref alloc (int size);
|
||||
void free (int size) { wasted_ += size; }
|
||||
|
||||
// Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
|
||||
T& operator[](Ref r) { assert(r >= 0 && r < sz); return memory[r]; }
|
||||
const T& operator[](Ref r) const { assert(r >= 0 && r < sz); return memory[r]; }
|
||||
|
||||
T* lea (Ref r) { assert(r >= 0 && r < sz); return &memory[r]; }
|
||||
const T* lea (Ref r) const { assert(r >= 0 && r < sz); return &memory[r]; }
|
||||
Ref ael (const T* t) { assert((void*)t >= (void*)&memory[0] && (void*)t < (void*)&memory[sz-1]);
|
||||
return (Ref)(t - &memory[0]); }
|
||||
|
||||
void moveTo(RegionAllocator& to) {
|
||||
if (to.memory != NULL) ::free(to.memory);
|
||||
to.memory = memory;
|
||||
to.sz = sz;
|
||||
to.cap = cap;
|
||||
to.wasted_ = wasted_;
|
||||
|
||||
memory = NULL;
|
||||
sz = cap = wasted_ = 0;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
void RegionAllocator<T>::capacity(uint32_t min_cap)
|
||||
{
|
||||
if (cap >= min_cap) return;
|
||||
|
||||
uint32_t prev_cap = cap;
|
||||
while (cap < min_cap){
|
||||
// NOTE: Multiply by a factor (13/8) without causing overflow, then add 2 and make the
|
||||
// result even by clearing the least significant bit. The resulting sequence of capacities
|
||||
// is carefully chosen to hit a maximum capacity that is close to the '2^32-1' limit when
|
||||
// using 'uint32_t' as indices so that as much as possible of this space can be used.
|
||||
uint32_t delta = ((cap >> 1) + (cap >> 3) + 2) & ~1;
|
||||
cap += delta;
|
||||
|
||||
if (cap <= prev_cap)
|
||||
throw OutOfMemoryException();
|
||||
}
|
||||
// printf(" .. (%p) cap = %u\n", this, cap);
|
||||
|
||||
assert(cap > 0);
|
||||
memory = (T*)xrealloc(memory, sizeof(T)*cap);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
typename RegionAllocator<T>::Ref
|
||||
RegionAllocator<T>::alloc(int size)
|
||||
{
|
||||
// printf("ALLOC called (this = %p, size = %d)\n", this, size); fflush(stdout);
|
||||
assert(size > 0);
|
||||
capacity(sz + size);
|
||||
|
||||
uint32_t prev_sz = sz;
|
||||
sz += size;
|
||||
|
||||
// Handle overflow:
|
||||
if (sz < prev_sz)
|
||||
throw OutOfMemoryException();
|
||||
|
||||
return prev_sz;
|
||||
}
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
148
contrib/minisat/src/mtl/Heap.h
Normal file
148
contrib/minisat/src/mtl/Heap.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/******************************************************************************************[Heap.h]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Heap_h
|
||||
#define Minisat_Heap_h
|
||||
|
||||
#include "mtl/Vec.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// A heap implementation with support for decrease/increase key.
|
||||
|
||||
|
||||
template<class Comp>
|
||||
class Heap {
|
||||
Comp lt; // The heap is a minimum-heap with respect to this comparator
|
||||
vec<int> heap; // Heap of integers
|
||||
vec<int> indices; // Each integers position (index) in the Heap
|
||||
|
||||
// Index "traversal" functions
|
||||
static inline int left (int i) { return i*2+1; }
|
||||
static inline int right (int i) { return (i+1)*2; }
|
||||
static inline int parent(int i) { return (i-1) >> 1; }
|
||||
|
||||
|
||||
void percolateUp(int i)
|
||||
{
|
||||
int x = heap[i];
|
||||
int p = parent(i);
|
||||
|
||||
while (i != 0 && lt(x, heap[p])){
|
||||
heap[i] = heap[p];
|
||||
indices[heap[p]] = i;
|
||||
i = p;
|
||||
p = parent(p);
|
||||
}
|
||||
heap [i] = x;
|
||||
indices[x] = i;
|
||||
}
|
||||
|
||||
|
||||
void percolateDown(int i)
|
||||
{
|
||||
int x = heap[i];
|
||||
while (left(i) < heap.size()){
|
||||
int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
|
||||
if (!lt(heap[child], x)) break;
|
||||
heap[i] = heap[child];
|
||||
indices[heap[i]] = i;
|
||||
i = child;
|
||||
}
|
||||
heap [i] = x;
|
||||
indices[x] = i;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
Heap(const Comp& c) : lt(c) { }
|
||||
|
||||
int size () const { return heap.size(); }
|
||||
bool empty () const { return heap.size() == 0; }
|
||||
bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; }
|
||||
int operator[](int index) const { assert(index < heap.size()); return heap[index]; }
|
||||
|
||||
|
||||
void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); }
|
||||
void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
|
||||
|
||||
|
||||
// Safe variant of insert/decrease/increase:
|
||||
void update(int n)
|
||||
{
|
||||
if (!inHeap(n))
|
||||
insert(n);
|
||||
else {
|
||||
percolateUp(indices[n]);
|
||||
percolateDown(indices[n]); }
|
||||
}
|
||||
|
||||
|
||||
void insert(int n)
|
||||
{
|
||||
indices.growTo(n+1, -1);
|
||||
assert(!inHeap(n));
|
||||
|
||||
indices[n] = heap.size();
|
||||
heap.push(n);
|
||||
percolateUp(indices[n]);
|
||||
}
|
||||
|
||||
|
||||
int removeMin()
|
||||
{
|
||||
int x = heap[0];
|
||||
heap[0] = heap.last();
|
||||
indices[heap[0]] = 0;
|
||||
indices[x] = -1;
|
||||
heap.pop();
|
||||
if (heap.size() > 1) percolateDown(0);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
// Rebuild the heap from scratch, using the elements in 'ns':
|
||||
void build(vec<int>& ns) {
|
||||
for (int i = 0; i < heap.size(); i++)
|
||||
indices[heap[i]] = -1;
|
||||
heap.clear();
|
||||
|
||||
for (int i = 0; i < ns.size(); i++){
|
||||
indices[ns[i]] = i;
|
||||
heap.push(ns[i]); }
|
||||
|
||||
for (int i = heap.size() / 2 - 1; i >= 0; i--)
|
||||
percolateDown(i);
|
||||
}
|
||||
|
||||
void clear(bool dealloc = false)
|
||||
{
|
||||
for (int i = 0; i < heap.size(); i++)
|
||||
indices[heap[i]] = -1;
|
||||
heap.clear(dealloc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
42
contrib/minisat/src/mtl/IntTypes.h
Normal file
42
contrib/minisat/src/mtl/IntTypes.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/**************************************************************************************[IntTypes.h]
|
||||
Copyright (c) 2009-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_IntTypes_h
|
||||
#define Minisat_IntTypes_h
|
||||
|
||||
#ifdef __sun
|
||||
// Not sure if there are newer versions that support C99 headers. The
|
||||
// needed features are implemented in the headers below though:
|
||||
|
||||
# include <sys/int_types.h>
|
||||
# include <sys/int_fmtio.h>
|
||||
# include <sys/int_limits.h>
|
||||
|
||||
#else
|
||||
|
||||
# include <stdint.h>
|
||||
# include <inttypes.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
#endif
|
193
contrib/minisat/src/mtl/Map.h
Normal file
193
contrib/minisat/src/mtl/Map.h
Normal file
@@ -0,0 +1,193 @@
|
||||
/*******************************************************************************************[Map.h]
|
||||
Copyright (c) 2006-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Map_h
|
||||
#define Minisat_Map_h
|
||||
|
||||
#include "mtl/IntTypes.h"
|
||||
#include "mtl/Vec.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// Default hash/equals functions
|
||||
//
|
||||
|
||||
template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
|
||||
template<class K> struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
|
||||
|
||||
template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
|
||||
template<class K> struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
|
||||
|
||||
static inline uint32_t hash(uint32_t x){ return x; }
|
||||
static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
|
||||
static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
|
||||
static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Some primes
|
||||
//
|
||||
|
||||
static const int nprimes = 25;
|
||||
static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 };
|
||||
|
||||
//=================================================================================================
|
||||
// Hash table implementation of Maps
|
||||
//
|
||||
|
||||
template<class K, class D, class H = Hash<K>, class E = Equal<K> >
|
||||
class Map {
|
||||
public:
|
||||
struct Pair { K key; D data; };
|
||||
|
||||
private:
|
||||
H hash;
|
||||
E equals;
|
||||
|
||||
vec<Pair>* table;
|
||||
int cap;
|
||||
int size;
|
||||
|
||||
// Don't allow copying (error prone):
|
||||
Map<K,D,H,E>& operator = (Map<K,D,H,E>& other) { assert(0); }
|
||||
Map (Map<K,D,H,E>& other) { assert(0); }
|
||||
|
||||
bool checkCap(int new_size) const { return new_size > cap; }
|
||||
|
||||
int32_t index (const K& k) const { return hash(k) % cap; }
|
||||
void _insert (const K& k, const D& d) {
|
||||
vec<Pair>& ps = table[index(k)];
|
||||
ps.push(); ps.last().key = k; ps.last().data = d; }
|
||||
|
||||
void rehash () {
|
||||
const vec<Pair>* old = table;
|
||||
|
||||
int old_cap = cap;
|
||||
int newsize = primes[0];
|
||||
for (int i = 1; newsize <= cap && i < nprimes; i++)
|
||||
newsize = primes[i];
|
||||
|
||||
table = new vec<Pair>[newsize];
|
||||
cap = newsize;
|
||||
|
||||
for (int i = 0; i < old_cap; i++){
|
||||
for (int j = 0; j < old[i].size(); j++){
|
||||
_insert(old[i][j].key, old[i][j].data); }}
|
||||
|
||||
delete [] old;
|
||||
|
||||
// printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Map () : table(NULL), cap(0), size(0) {}
|
||||
Map (const H& h, const E& e) : hash(h), equals(e), table(NULL), cap(0), size(0){}
|
||||
~Map () { delete [] table; }
|
||||
|
||||
// PRECONDITION: the key must already exist in the map.
|
||||
const D& operator [] (const K& k) const
|
||||
{
|
||||
assert(size != 0);
|
||||
const D* res = NULL;
|
||||
const vec<Pair>& ps = table[index(k)];
|
||||
for (int i = 0; i < ps.size(); i++)
|
||||
if (equals(ps[i].key, k))
|
||||
res = &ps[i].data;
|
||||
assert(res != NULL);
|
||||
return *res;
|
||||
}
|
||||
|
||||
// PRECONDITION: the key must already exist in the map.
|
||||
D& operator [] (const K& k)
|
||||
{
|
||||
assert(size != 0);
|
||||
D* res = NULL;
|
||||
vec<Pair>& ps = table[index(k)];
|
||||
for (int i = 0; i < ps.size(); i++)
|
||||
if (equals(ps[i].key, k))
|
||||
res = &ps[i].data;
|
||||
assert(res != NULL);
|
||||
return *res;
|
||||
}
|
||||
|
||||
// PRECONDITION: the key must *NOT* exist in the map.
|
||||
void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; }
|
||||
bool peek (const K& k, D& d) const {
|
||||
if (size == 0) return false;
|
||||
const vec<Pair>& ps = table[index(k)];
|
||||
for (int i = 0; i < ps.size(); i++)
|
||||
if (equals(ps[i].key, k)){
|
||||
d = ps[i].data;
|
||||
return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
bool has (const K& k) const {
|
||||
if (size == 0) return false;
|
||||
const vec<Pair>& ps = table[index(k)];
|
||||
for (int i = 0; i < ps.size(); i++)
|
||||
if (equals(ps[i].key, k))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// PRECONDITION: the key must exist in the map.
|
||||
void remove(const K& k) {
|
||||
assert(table != NULL);
|
||||
vec<Pair>& ps = table[index(k)];
|
||||
int j = 0;
|
||||
for (; j < ps.size() && !equals(ps[j].key, k); j++);
|
||||
assert(j < ps.size());
|
||||
ps[j] = ps.last();
|
||||
ps.pop();
|
||||
size--;
|
||||
}
|
||||
|
||||
void clear () {
|
||||
cap = size = 0;
|
||||
delete [] table;
|
||||
table = NULL;
|
||||
}
|
||||
|
||||
int elems() const { return size; }
|
||||
int bucket_count() const { return cap; }
|
||||
|
||||
// NOTE: the hash and equality objects are not moved by this method:
|
||||
void moveTo(Map& other){
|
||||
delete [] other.table;
|
||||
|
||||
other.table = table;
|
||||
other.cap = cap;
|
||||
other.size = size;
|
||||
|
||||
table = NULL;
|
||||
size = cap = 0;
|
||||
}
|
||||
|
||||
// NOTE: given a bit more time, I could make a more C++-style iterator out of this:
|
||||
const vec<Pair>& bucket(int i) const { return table[i]; }
|
||||
};
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
69
contrib/minisat/src/mtl/Queue.h
Normal file
69
contrib/minisat/src/mtl/Queue.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*****************************************************************************************[Queue.h]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Queue_h
|
||||
#define Minisat_Queue_h
|
||||
|
||||
#include "mtl/Vec.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
template<class T>
|
||||
class Queue {
|
||||
vec<T> buf;
|
||||
int first;
|
||||
int end;
|
||||
|
||||
public:
|
||||
typedef T Key;
|
||||
|
||||
Queue() : buf(1), first(0), end(0) {}
|
||||
|
||||
void clear (bool dealloc = false) { buf.clear(dealloc); buf.growTo(1); first = end = 0; }
|
||||
int size () const { return (end >= first) ? end - first : end - first + buf.size(); }
|
||||
|
||||
const T& operator [] (int index) const { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
|
||||
T& operator [] (int index) { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
|
||||
|
||||
T peek () const { assert(first != end); return buf[first]; }
|
||||
void pop () { assert(first != end); first++; if (first == buf.size()) first = 0; }
|
||||
void insert(T elem) { // INVARIANT: buf[end] is always unused
|
||||
buf[end++] = elem;
|
||||
if (end == buf.size()) end = 0;
|
||||
if (first == end){ // Resize:
|
||||
vec<T> tmp((buf.size()*3 + 1) >> 1);
|
||||
//**/printf("queue alloc: %d elems (%.1f MB)\n", tmp.size(), tmp.size() * sizeof(T) / 1000000.0);
|
||||
int i = 0;
|
||||
for (int j = first; j < buf.size(); j++) tmp[i++] = buf[j];
|
||||
for (int j = 0 ; j < end ; j++) tmp[i++] = buf[j];
|
||||
first = 0;
|
||||
end = buf.size();
|
||||
tmp.moveTo(buf);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
98
contrib/minisat/src/mtl/Sort.h
Normal file
98
contrib/minisat/src/mtl/Sort.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/******************************************************************************************[Sort.h]
|
||||
Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Sort_h
|
||||
#define Minisat_Sort_h
|
||||
|
||||
#include "mtl/Vec.h"
|
||||
|
||||
//=================================================================================================
|
||||
// Some sorting algorithms for vec's
|
||||
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
template<class T>
|
||||
struct LessThan_default {
|
||||
bool operator () (T x, T y) { return x < y; }
|
||||
};
|
||||
|
||||
|
||||
template <class T, class LessThan>
|
||||
void selectionSort(T* array, int size, LessThan lt)
|
||||
{
|
||||
int i, j, best_i;
|
||||
T tmp;
|
||||
|
||||
for (i = 0; i < size-1; i++){
|
||||
best_i = i;
|
||||
for (j = i+1; j < size; j++){
|
||||
if (lt(array[j], array[best_i]))
|
||||
best_i = j;
|
||||
}
|
||||
tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
|
||||
}
|
||||
}
|
||||
template <class T> static inline void selectionSort(T* array, int size) {
|
||||
selectionSort(array, size, LessThan_default<T>()); }
|
||||
|
||||
template <class T, class LessThan>
|
||||
void sort(T* array, int size, LessThan lt)
|
||||
{
|
||||
if (size <= 15)
|
||||
selectionSort(array, size, lt);
|
||||
|
||||
else{
|
||||
T pivot = array[size / 2];
|
||||
T tmp;
|
||||
int i = -1;
|
||||
int j = size;
|
||||
|
||||
for(;;){
|
||||
do i++; while(lt(array[i], pivot));
|
||||
do j--; while(lt(pivot, array[j]));
|
||||
|
||||
if (i >= j) break;
|
||||
|
||||
tmp = array[i]; array[i] = array[j]; array[j] = tmp;
|
||||
}
|
||||
|
||||
sort(array , i , lt);
|
||||
sort(&array[i], size-i, lt);
|
||||
}
|
||||
}
|
||||
template <class T> static inline void sort(T* array, int size) {
|
||||
sort(array, size, LessThan_default<T>()); }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// For 'vec's:
|
||||
|
||||
|
||||
template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
|
||||
sort((T*)v, v.size(), lt); }
|
||||
template <class T> void sort(vec<T>& v) {
|
||||
sort(v, LessThan_default<T>()); }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
130
contrib/minisat/src/mtl/Vec.h
Normal file
130
contrib/minisat/src/mtl/Vec.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*******************************************************************************************[Vec.h]
|
||||
Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Vec_h
|
||||
#define Minisat_Vec_h
|
||||
|
||||
#include <assert.h>
|
||||
#include <new>
|
||||
|
||||
#include "mtl/IntTypes.h"
|
||||
#include "mtl/XAlloc.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// Automatically resizable arrays
|
||||
//
|
||||
// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
|
||||
|
||||
template<class T>
|
||||
class vec {
|
||||
T* data;
|
||||
int sz;
|
||||
int cap;
|
||||
|
||||
// Don't allow copying (error prone):
|
||||
vec<T>& operator = (vec<T>& other) { assert(0); return *this; }
|
||||
vec (vec<T>& other) { assert(0); }
|
||||
|
||||
// Helpers for calculating next capacity:
|
||||
static inline int imax (int x, int y) { int mask = (y-x) >> (sizeof(int)*8-1); return (x&mask) + (y&(~mask)); }
|
||||
//static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
|
||||
static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
|
||||
|
||||
public:
|
||||
// Constructors:
|
||||
vec() : data(NULL) , sz(0) , cap(0) { }
|
||||
explicit vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); }
|
||||
vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); }
|
||||
~vec() { clear(true); }
|
||||
|
||||
// Pointer to first element:
|
||||
operator T* (void) { return data; }
|
||||
|
||||
// Size operations:
|
||||
int size (void) const { return sz; }
|
||||
void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }
|
||||
void shrink_ (int nelems) { assert(nelems <= sz); sz -= nelems; }
|
||||
int capacity (void) const { return cap; }
|
||||
void capacity (int min_cap);
|
||||
void growTo (int size);
|
||||
void growTo (int size, const T& pad);
|
||||
void clear (bool dealloc = false);
|
||||
|
||||
// Stack interface:
|
||||
void push (void) { if (sz == cap) capacity(sz+1); new (&data[sz]) T(); sz++; }
|
||||
void push (const T& elem) { if (sz == cap) capacity(sz+1); data[sz++] = elem; }
|
||||
void push_ (const T& elem) { assert(sz < cap); data[sz++] = elem; }
|
||||
void pop (void) { assert(sz > 0); sz--, data[sz].~T(); }
|
||||
// NOTE: it seems possible that overflow can happen in the 'sz+1' expression of 'push()', but
|
||||
// in fact it can not since it requires that 'cap' is equal to INT_MAX. This in turn can not
|
||||
// happen given the way capacities are calculated (below). Essentially, all capacities are
|
||||
// even, but INT_MAX is odd.
|
||||
|
||||
const T& last (void) const { return data[sz-1]; }
|
||||
T& last (void) { return data[sz-1]; }
|
||||
|
||||
// Vector interface:
|
||||
const T& operator [] (int index) const { return data[index]; }
|
||||
T& operator [] (int index) { return data[index]; }
|
||||
|
||||
// Duplicatation (preferred instead):
|
||||
void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
|
||||
void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
void vec<T>::capacity(int min_cap) {
|
||||
if (cap >= min_cap) return;
|
||||
int add = imax((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1); // NOTE: grow by approximately 3/2
|
||||
if (add > INT_MAX - cap || ((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM)
|
||||
throw OutOfMemoryException();
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void vec<T>::growTo(int size, const T& pad) {
|
||||
if (sz >= size) return;
|
||||
capacity(size);
|
||||
for (int i = sz; i < size; i++) data[i] = pad;
|
||||
sz = size; }
|
||||
|
||||
|
||||
template<class T>
|
||||
void vec<T>::growTo(int size) {
|
||||
if (sz >= size) return;
|
||||
capacity(size);
|
||||
for (int i = sz; i < size; i++) new (&data[i]) T();
|
||||
sz = size; }
|
||||
|
||||
|
||||
template<class T>
|
||||
void vec<T>::clear(bool dealloc) {
|
||||
if (data != NULL){
|
||||
for (int i = 0; i < sz; i++) data[i].~T();
|
||||
sz = 0;
|
||||
if (dealloc) free(data), data = NULL, cap = 0; } }
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
45
contrib/minisat/src/mtl/XAlloc.h
Normal file
45
contrib/minisat/src/mtl/XAlloc.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************************[XAlloc.h]
|
||||
Copyright (c) 2009-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
|
||||
#ifndef Minisat_XAlloc_h
|
||||
#define Minisat_XAlloc_h
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
// Simple layer on top of malloc/realloc to catch out-of-memory situtaions and provide some typing:
|
||||
|
||||
class OutOfMemoryException{};
|
||||
static inline void* xrealloc(void *ptr, size_t size)
|
||||
{
|
||||
void* mem = realloc(ptr, size);
|
||||
if (mem == NULL && errno == ENOMEM){
|
||||
throw OutOfMemoryException();
|
||||
}else
|
||||
return mem;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
6
contrib/minisat/src/mtl/config.mk
Normal file
6
contrib/minisat/src/mtl/config.mk
Normal file
@@ -0,0 +1,6 @@
|
||||
##
|
||||
## This file is for system specific configurations. For instance, on
|
||||
## some systems the path to zlib needs to be added. Example:
|
||||
##
|
||||
## CFLAGS += -I/usr/local/include
|
||||
## LFLAGS += -L/usr/local/lib
|
107
contrib/minisat/src/mtl/template.mk
Normal file
107
contrib/minisat/src/mtl/template.mk
Normal file
@@ -0,0 +1,107 @@
|
||||
##
|
||||
## Template makefile for Standard, Profile, Debug, Release, and Release-static versions
|
||||
##
|
||||
## eg: "make rs" for a statically linked release version.
|
||||
## "make d" for a debug version (no optimizations).
|
||||
## "make" for the standard version (optimized, but with debug information and assertions active)
|
||||
|
||||
PWD = $(shell pwd)
|
||||
EXEC ?= $(notdir $(PWD))
|
||||
|
||||
CSRCS = $(wildcard $(PWD)/*.cc)
|
||||
DSRCS = $(foreach dir, $(DEPDIR), $(filter-out $(MROOT)/$(dir)/Main.cc, $(wildcard $(MROOT)/$(dir)/*.cc)))
|
||||
CHDRS = $(wildcard $(PWD)/*.h)
|
||||
COBJS = $(CSRCS:.cc=.o) $(DSRCS:.cc=.o)
|
||||
|
||||
PCOBJS = $(addsuffix p, $(COBJS))
|
||||
DCOBJS = $(addsuffix d, $(COBJS))
|
||||
RCOBJS = $(addsuffix r, $(COBJS))
|
||||
|
||||
|
||||
CXX ?= g++
|
||||
CFLAGS ?= -Wall -Wno-parentheses
|
||||
LFLAGS ?= -Wall
|
||||
|
||||
COPTIMIZE ?= -O3
|
||||
|
||||
CFLAGS += -I$(MROOT) -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS
|
||||
LFLAGS += -lz
|
||||
|
||||
.PHONY : s p d r rs clean
|
||||
|
||||
s: $(EXEC)
|
||||
p: $(EXEC)_profile
|
||||
d: $(EXEC)_debug
|
||||
r: $(EXEC)_release
|
||||
rs: $(EXEC)_static
|
||||
|
||||
libs: lib$(LIB)_standard.a
|
||||
libp: lib$(LIB)_profile.a
|
||||
libd: lib$(LIB)_debug.a
|
||||
libr: lib$(LIB)_release.a
|
||||
|
||||
## Compile options
|
||||
%.o: CFLAGS +=$(COPTIMIZE) -g -D DEBUG
|
||||
%.op: CFLAGS +=$(COPTIMIZE) -pg -g -D NDEBUG
|
||||
%.od: CFLAGS +=-O0 -g -D DEBUG
|
||||
%.or: CFLAGS +=$(COPTIMIZE) -g -D NDEBUG
|
||||
|
||||
## Link options
|
||||
$(EXEC): LFLAGS += -g
|
||||
$(EXEC)_profile: LFLAGS += -g -pg
|
||||
$(EXEC)_debug: LFLAGS += -g
|
||||
#$(EXEC)_release: LFLAGS += ...
|
||||
$(EXEC)_static: LFLAGS += --static
|
||||
|
||||
## Dependencies
|
||||
$(EXEC): $(COBJS)
|
||||
$(EXEC)_profile: $(PCOBJS)
|
||||
$(EXEC)_debug: $(DCOBJS)
|
||||
$(EXEC)_release: $(RCOBJS)
|
||||
$(EXEC)_static: $(RCOBJS)
|
||||
|
||||
lib$(LIB)_standard.a: $(filter-out */Main.o, $(COBJS))
|
||||
lib$(LIB)_profile.a: $(filter-out */Main.op, $(PCOBJS))
|
||||
lib$(LIB)_debug.a: $(filter-out */Main.od, $(DCOBJS))
|
||||
lib$(LIB)_release.a: $(filter-out */Main.or, $(RCOBJS))
|
||||
|
||||
|
||||
## Build rule
|
||||
%.o %.op %.od %.or: %.cc
|
||||
@echo Compiling: $(subst $(MROOT)/,,$@)
|
||||
@$(CXX) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
## Linking rules (standard/profile/debug/release)
|
||||
$(EXEC) $(EXEC)_profile $(EXEC)_debug $(EXEC)_release $(EXEC)_static:
|
||||
@echo Linking: "$@ ( $(foreach f,$^,$(subst $(MROOT)/,,$f)) )"
|
||||
@$(CXX) $^ $(LFLAGS) -o $@
|
||||
|
||||
## Library rules (standard/profile/debug/release)
|
||||
lib$(LIB)_standard.a lib$(LIB)_profile.a lib$(LIB)_release.a lib$(LIB)_debug.a:
|
||||
@echo Making library: "$@ ( $(foreach f,$^,$(subst $(MROOT)/,,$f)) )"
|
||||
@$(AR) -rcsv $@ $^
|
||||
|
||||
## Library Soft Link rule:
|
||||
libs libp libd libr:
|
||||
@echo "Making Soft Link: $^ -> lib$(LIB).a"
|
||||
@ln -sf $^ lib$(LIB).a
|
||||
|
||||
## Clean rule
|
||||
clean:
|
||||
@rm -f $(EXEC) $(EXEC)_profile $(EXEC)_debug $(EXEC)_release $(EXEC)_static \
|
||||
$(COBJS) $(PCOBJS) $(DCOBJS) $(RCOBJS) *.core depend.mk
|
||||
|
||||
## Make dependencies
|
||||
depend.mk: $(CSRCS) $(CHDRS)
|
||||
@echo Making dependencies
|
||||
@$(CXX) $(CFLAGS) -I$(MROOT) \
|
||||
$(CSRCS) -MM | sed 's|\(.*\):|$(PWD)/\1 $(PWD)/\1r $(PWD)/\1d $(PWD)/\1p:|' > depend.mk
|
||||
@for dir in $(DEPDIR); do \
|
||||
if [ -r $(MROOT)/$${dir}/depend.mk ]; then \
|
||||
echo Depends on: $${dir}; \
|
||||
cat $(MROOT)/$${dir}/depend.mk >> depend.mk; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
-include $(MROOT)/mtl/config.mk
|
||||
-include depend.mk
|
211
contrib/minisat/src/simp/Main.cc
Normal file
211
contrib/minisat/src/simp/Main.cc
Normal file
@@ -0,0 +1,211 @@
|
||||
/*****************************************************************************************[Main.cc]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <zlib.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "utils/System.h"
|
||||
#include "utils/ParseUtils.h"
|
||||
#include "utils/Options.h"
|
||||
#include "core/Dimacs.h"
|
||||
#include "simp/SimpSolver.h"
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
|
||||
void printStats(Solver& solver)
|
||||
{
|
||||
double cpu_time = cpuTime();
|
||||
double mem_used = memUsedPeak();
|
||||
printf("restarts : %"PRIu64"\n", solver.starts);
|
||||
printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", solver.conflicts , solver.conflicts /cpu_time);
|
||||
printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions /cpu_time);
|
||||
printf("propagations : %-12"PRIu64" (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time);
|
||||
printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals);
|
||||
if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used);
|
||||
printf("CPU time : %g s\n", cpu_time);
|
||||
}
|
||||
|
||||
|
||||
static Solver* solver;
|
||||
// Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case
|
||||
// for this feature of the Solver as it may take longer than an immediate call to '_exit()'.
|
||||
static void SIGINT_interrupt(int signum) { solver->interrupt(); }
|
||||
|
||||
// Note that '_exit()' rather than 'exit()' has to be used. The reason is that 'exit()' calls
|
||||
// destructors and may cause deadlocks if a malloc/free function happens to be running (these
|
||||
// functions are guarded by locks for multithreaded use).
|
||||
static void SIGINT_exit(int signum) {
|
||||
printf("\n"); printf("*** INTERRUPTED ***\n");
|
||||
if (solver->verbosity > 0){
|
||||
printStats(*solver);
|
||||
printf("\n"); printf("*** INTERRUPTED ***\n"); }
|
||||
_exit(1); }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Main:
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
try {
|
||||
setUsageHelp("USAGE: %s [options] <input-file> <result-output-file>\n\n where input may be either in plain or gzipped DIMACS.\n");
|
||||
// printf("This is MiniSat 2.0 beta\n");
|
||||
|
||||
#if defined(__linux__)
|
||||
fpu_control_t oldcw, newcw;
|
||||
_FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
|
||||
printf("WARNING: for repeatability, setting FPU to use double precision\n");
|
||||
#endif
|
||||
// Extra options:
|
||||
//
|
||||
IntOption verb ("MAIN", "verb", "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2));
|
||||
BoolOption pre ("MAIN", "pre", "Completely turn on/off any preprocessing.", true);
|
||||
StringOption dimacs ("MAIN", "dimacs", "If given, stop after preprocessing and write the result to this file.");
|
||||
IntOption cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX));
|
||||
IntOption mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX));
|
||||
|
||||
parseOptions(argc, argv, true);
|
||||
|
||||
SimpSolver S;
|
||||
double initial_time = cpuTime();
|
||||
|
||||
if (!pre) S.eliminate(true);
|
||||
|
||||
S.verbosity = verb;
|
||||
|
||||
solver = &S;
|
||||
// Use signal handlers that forcibly quit until the solver will be able to respond to
|
||||
// interrupts:
|
||||
signal(SIGINT, SIGINT_exit);
|
||||
signal(SIGXCPU,SIGINT_exit);
|
||||
|
||||
// Set limit on CPU-time:
|
||||
if (cpu_lim != INT32_MAX){
|
||||
rlimit rl;
|
||||
getrlimit(RLIMIT_CPU, &rl);
|
||||
if (rl.rlim_max == RLIM_INFINITY || (rlim_t)cpu_lim < rl.rlim_max){
|
||||
rl.rlim_cur = cpu_lim;
|
||||
if (setrlimit(RLIMIT_CPU, &rl) == -1)
|
||||
printf("WARNING! Could not set resource limit: CPU-time.\n");
|
||||
} }
|
||||
|
||||
// Set limit on virtual memory:
|
||||
if (mem_lim != INT32_MAX){
|
||||
rlim_t new_mem_lim = (rlim_t)mem_lim * 1024*1024;
|
||||
rlimit rl;
|
||||
getrlimit(RLIMIT_AS, &rl);
|
||||
if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){
|
||||
rl.rlim_cur = new_mem_lim;
|
||||
if (setrlimit(RLIMIT_AS, &rl) == -1)
|
||||
printf("WARNING! Could not set resource limit: Virtual memory.\n");
|
||||
} }
|
||||
|
||||
if (argc == 1)
|
||||
printf("Reading from standard input... Use '--help' for help.\n");
|
||||
|
||||
gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
|
||||
if (in == NULL)
|
||||
printf("ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]), exit(1);
|
||||
|
||||
if (S.verbosity > 0){
|
||||
printf("============================[ Problem Statistics ]=============================\n");
|
||||
printf("| |\n"); }
|
||||
|
||||
parse_DIMACS(in, S);
|
||||
gzclose(in);
|
||||
FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;
|
||||
|
||||
if (S.verbosity > 0){
|
||||
printf("| Number of variables: %12d |\n", S.nVars());
|
||||
printf("| Number of clauses: %12d |\n", S.nClauses()); }
|
||||
|
||||
double parsed_time = cpuTime();
|
||||
if (S.verbosity > 0)
|
||||
printf("| Parse time: %12.2f s |\n", parsed_time - initial_time);
|
||||
|
||||
// Change to signal-handlers that will only notify the solver and allow it to terminate
|
||||
// voluntarily:
|
||||
signal(SIGINT, SIGINT_interrupt);
|
||||
signal(SIGXCPU,SIGINT_interrupt);
|
||||
|
||||
S.eliminate(true);
|
||||
double simplified_time = cpuTime();
|
||||
if (S.verbosity > 0){
|
||||
printf("| Simplification time: %12.2f s |\n", simplified_time - parsed_time);
|
||||
printf("| |\n"); }
|
||||
|
||||
if (!S.okay()){
|
||||
if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res);
|
||||
if (S.verbosity > 0){
|
||||
printf("===============================================================================\n");
|
||||
printf("Solved by simplification\n");
|
||||
printStats(S);
|
||||
printf("\n"); }
|
||||
printf("UNSATISFIABLE\n");
|
||||
exit(20);
|
||||
}
|
||||
|
||||
if (dimacs){
|
||||
if (S.verbosity > 0)
|
||||
printf("==============================[ Writing DIMACS ]===============================\n");
|
||||
S.toDimacs((const char*)dimacs);
|
||||
if (S.verbosity > 0)
|
||||
printStats(S);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
vec<Lit> dummy;
|
||||
lbool ret = S.solveLimited(dummy);
|
||||
|
||||
if (S.verbosity > 0){
|
||||
printStats(S);
|
||||
printf("\n"); }
|
||||
printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n");
|
||||
if (res != NULL){
|
||||
if (ret == l_True){
|
||||
fprintf(res, "SAT\n");
|
||||
for (int i = 0; i < S.nVars(); i++)
|
||||
if (S.model[i] != l_Undef)
|
||||
fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1);
|
||||
fprintf(res, " 0\n");
|
||||
}else if (ret == l_False)
|
||||
fprintf(res, "UNSAT\n");
|
||||
else
|
||||
fprintf(res, "INDET\n");
|
||||
fclose(res);
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
exit(ret == l_True ? 10 : ret == l_False ? 20 : 0); // (faster than "return", which will invoke the destructor for 'Solver')
|
||||
#else
|
||||
return (ret == l_True ? 10 : ret == l_False ? 20 : 0);
|
||||
#endif
|
||||
} catch (OutOfMemoryException&){
|
||||
printf("===============================================================================\n");
|
||||
printf("INDETERMINATE\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
4
contrib/minisat/src/simp/Makefile
Normal file
4
contrib/minisat/src/simp/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
EXEC = minisat
|
||||
DEPDIR = mtl utils core
|
||||
|
||||
include $(MROOT)/mtl/template.mk
|
717
contrib/minisat/src/simp/SimpSolver.cc
Normal file
717
contrib/minisat/src/simp/SimpSolver.cc
Normal file
@@ -0,0 +1,717 @@
|
||||
/***********************************************************************************[SimpSolver.cc]
|
||||
Copyright (c) 2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include "mtl/Sort.h"
|
||||
#include "simp/SimpSolver.h"
|
||||
#include "utils/System.h"
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
//=================================================================================================
|
||||
// Options:
|
||||
|
||||
|
||||
static const char* _cat = "SIMP";
|
||||
|
||||
static BoolOption opt_use_asymm (_cat, "asymm", "Shrink clauses by asymmetric branching.", false);
|
||||
static BoolOption opt_use_rcheck (_cat, "rcheck", "Check if a clause is already implied. (costly)", false);
|
||||
static BoolOption opt_use_elim (_cat, "elim", "Perform variable elimination.", true);
|
||||
static IntOption opt_grow (_cat, "grow", "Allow a variable elimination step to grow by a number of clauses.", 0);
|
||||
static IntOption opt_clause_lim (_cat, "cl-lim", "Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20, IntRange(-1, INT32_MAX));
|
||||
static IntOption opt_subsumption_lim (_cat, "sub-lim", "Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX));
|
||||
static DoubleOption opt_simp_garbage_frac(_cat, "simp-gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered during simplification.", 0.5, DoubleRange(0, false, HUGE_VAL, false));
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Constructor/Destructor:
|
||||
|
||||
|
||||
SimpSolver::SimpSolver() :
|
||||
grow (opt_grow)
|
||||
, clause_lim (opt_clause_lim)
|
||||
, subsumption_lim (opt_subsumption_lim)
|
||||
, simp_garbage_frac (opt_simp_garbage_frac)
|
||||
, use_asymm (opt_use_asymm)
|
||||
, use_rcheck (opt_use_rcheck)
|
||||
, use_elim (opt_use_elim)
|
||||
, merges (0)
|
||||
, asymm_lits (0)
|
||||
, eliminated_vars (0)
|
||||
, elimorder (1)
|
||||
, use_simplification (true)
|
||||
, occurs (ClauseDeleted(ca))
|
||||
, elim_heap (ElimLt(n_occ))
|
||||
, bwdsub_assigns (0)
|
||||
, n_touched (0)
|
||||
{
|
||||
vec<Lit> dummy(1,lit_Undef);
|
||||
ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
|
||||
bwdsub_tmpunit = ca.alloc(dummy);
|
||||
remove_satisfied = false;
|
||||
}
|
||||
|
||||
|
||||
SimpSolver::~SimpSolver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Var SimpSolver::newVar(bool sign, bool dvar) {
|
||||
Var v = Solver::newVar(sign, dvar);
|
||||
|
||||
frozen .push((char)false);
|
||||
eliminated.push((char)false);
|
||||
|
||||
if (use_simplification){
|
||||
n_occ .push(0);
|
||||
n_occ .push(0);
|
||||
occurs .init(v);
|
||||
touched .push(0);
|
||||
elim_heap .insert(v);
|
||||
}
|
||||
return v; }
|
||||
|
||||
|
||||
|
||||
lbool SimpSolver::solve_(bool do_simp, bool turn_off_simp)
|
||||
{
|
||||
vec<Var> extra_frozen;
|
||||
lbool result = l_True;
|
||||
|
||||
do_simp &= use_simplification;
|
||||
|
||||
if (do_simp){
|
||||
// Assumptions must be temporarily frozen to run variable elimination:
|
||||
for (int i = 0; i < assumptions.size(); i++){
|
||||
Var v = var(assumptions[i]);
|
||||
|
||||
// If an assumption has been eliminated, remember it.
|
||||
assert(!isEliminated(v));
|
||||
|
||||
if (!frozen[v]){
|
||||
// Freeze and store.
|
||||
setFrozen(v, true);
|
||||
extra_frozen.push(v);
|
||||
} }
|
||||
|
||||
result = lbool(eliminate(turn_off_simp));
|
||||
}
|
||||
|
||||
if (result == l_True)
|
||||
result = Solver::solve_();
|
||||
else if (verbosity >= 1)
|
||||
printf("===============================================================================\n");
|
||||
|
||||
if (result == l_True)
|
||||
extendModel();
|
||||
|
||||
if (do_simp)
|
||||
// Unfreeze the assumptions that were frozen:
|
||||
for (int i = 0; i < extra_frozen.size(); i++)
|
||||
setFrozen(extra_frozen[i], false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SimpSolver::addClause_(vec<Lit>& ps)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
for (int i = 0; i < ps.size(); i++)
|
||||
assert(!isEliminated(var(ps[i])));
|
||||
#endif
|
||||
|
||||
int nclauses = clauses.size();
|
||||
|
||||
if (use_rcheck && implied(ps))
|
||||
return true;
|
||||
|
||||
if (!Solver::addClause_(ps))
|
||||
return false;
|
||||
|
||||
if (use_simplification && clauses.size() == nclauses + 1){
|
||||
CRef cr = clauses.last();
|
||||
const Clause& c = ca[cr];
|
||||
|
||||
// NOTE: the clause is added to the queue immediately and then
|
||||
// again during 'gatherTouchedClauses()'. If nothing happens
|
||||
// in between, it will only be checked once. Otherwise, it may
|
||||
// be checked twice unnecessarily. This is an unfortunate
|
||||
// consequence of how backward subsumption is used to mimic
|
||||
// forward subsumption.
|
||||
subsumption_queue.insert(cr);
|
||||
for (int i = 0; i < c.size(); i++){
|
||||
occurs[var(c[i])].push(cr);
|
||||
n_occ[toInt(c[i])]++;
|
||||
touched[var(c[i])] = 1;
|
||||
n_touched++;
|
||||
if (elim_heap.inHeap(var(c[i])))
|
||||
elim_heap.increase(var(c[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SimpSolver::removeClause(CRef cr)
|
||||
{
|
||||
const Clause& c = ca[cr];
|
||||
|
||||
if (use_simplification)
|
||||
for (int i = 0; i < c.size(); i++){
|
||||
n_occ[toInt(c[i])]--;
|
||||
updateElimHeap(var(c[i]));
|
||||
occurs.smudge(var(c[i]));
|
||||
}
|
||||
|
||||
Solver::removeClause(cr);
|
||||
}
|
||||
|
||||
|
||||
bool SimpSolver::strengthenClause(CRef cr, Lit l)
|
||||
{
|
||||
Clause& c = ca[cr];
|
||||
assert(decisionLevel() == 0);
|
||||
assert(use_simplification);
|
||||
|
||||
// FIX: this is too inefficient but would be nice to have (properly implemented)
|
||||
// if (!find(subsumption_queue, &c))
|
||||
subsumption_queue.insert(cr);
|
||||
|
||||
if (c.size() == 2){
|
||||
removeClause(cr);
|
||||
c.strengthen(l);
|
||||
}else{
|
||||
detachClause(cr, true);
|
||||
c.strengthen(l);
|
||||
attachClause(cr);
|
||||
remove(occurs[var(l)], cr);
|
||||
n_occ[toInt(l)]--;
|
||||
updateElimHeap(var(l));
|
||||
}
|
||||
|
||||
return c.size() == 1 ? enqueue(c[0]) && propagate() == CRef_Undef : true;
|
||||
}
|
||||
|
||||
|
||||
// Returns FALSE if clause is always satisfied ('out_clause' should not be used).
|
||||
bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
|
||||
{
|
||||
merges++;
|
||||
out_clause.clear();
|
||||
|
||||
bool ps_smallest = _ps.size() < _qs.size();
|
||||
const Clause& ps = ps_smallest ? _qs : _ps;
|
||||
const Clause& qs = ps_smallest ? _ps : _qs;
|
||||
|
||||
for (int i = 0; i < qs.size(); i++){
|
||||
if (var(qs[i]) != v){
|
||||
for (int j = 0; j < ps.size(); j++)
|
||||
if (var(ps[j]) == var(qs[i]))
|
||||
if (ps[j] == ~qs[i])
|
||||
return false;
|
||||
else
|
||||
goto next;
|
||||
out_clause.push(qs[i]);
|
||||
}
|
||||
next:;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ps.size(); i++)
|
||||
if (var(ps[i]) != v)
|
||||
out_clause.push(ps[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Returns FALSE if clause is always satisfied.
|
||||
bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size)
|
||||
{
|
||||
merges++;
|
||||
|
||||
bool ps_smallest = _ps.size() < _qs.size();
|
||||
const Clause& ps = ps_smallest ? _qs : _ps;
|
||||
const Clause& qs = ps_smallest ? _ps : _qs;
|
||||
const Lit* __ps = (const Lit*)ps;
|
||||
const Lit* __qs = (const Lit*)qs;
|
||||
|
||||
size = ps.size()-1;
|
||||
|
||||
for (int i = 0; i < qs.size(); i++){
|
||||
if (var(__qs[i]) != v){
|
||||
for (int j = 0; j < ps.size(); j++)
|
||||
if (var(__ps[j]) == var(__qs[i]))
|
||||
if (__ps[j] == ~__qs[i])
|
||||
return false;
|
||||
else
|
||||
goto next;
|
||||
size++;
|
||||
}
|
||||
next:;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SimpSolver::gatherTouchedClauses()
|
||||
{
|
||||
if (n_touched == 0) return;
|
||||
|
||||
int i,j;
|
||||
for (i = j = 0; i < subsumption_queue.size(); i++)
|
||||
if (ca[subsumption_queue[i]].mark() == 0)
|
||||
ca[subsumption_queue[i]].mark(2);
|
||||
|
||||
for (i = 0; i < touched.size(); i++)
|
||||
if (touched[i]){
|
||||
const vec<CRef>& cs = occurs.lookup(i);
|
||||
for (j = 0; j < cs.size(); j++)
|
||||
if (ca[cs[j]].mark() == 0){
|
||||
subsumption_queue.insert(cs[j]);
|
||||
ca[cs[j]].mark(2);
|
||||
}
|
||||
touched[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < subsumption_queue.size(); i++)
|
||||
if (ca[subsumption_queue[i]].mark() == 2)
|
||||
ca[subsumption_queue[i]].mark(0);
|
||||
|
||||
n_touched = 0;
|
||||
}
|
||||
|
||||
|
||||
bool SimpSolver::implied(const vec<Lit>& c)
|
||||
{
|
||||
assert(decisionLevel() == 0);
|
||||
|
||||
trail_lim.push(trail.size());
|
||||
for (int i = 0; i < c.size(); i++)
|
||||
if (value(c[i]) == l_True){
|
||||
cancelUntil(0);
|
||||
return false;
|
||||
}else if (value(c[i]) != l_False){
|
||||
assert(value(c[i]) == l_Undef);
|
||||
uncheckedEnqueue(~c[i]);
|
||||
}
|
||||
|
||||
bool result = propagate() != CRef_Undef;
|
||||
cancelUntil(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Backward subsumption + backward subsumption resolution
|
||||
bool SimpSolver::backwardSubsumptionCheck(bool verbose)
|
||||
{
|
||||
int cnt = 0;
|
||||
int subsumed = 0;
|
||||
int deleted_literals = 0;
|
||||
assert(decisionLevel() == 0);
|
||||
|
||||
while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){
|
||||
|
||||
// Empty subsumption queue and return immediately on user-interrupt:
|
||||
if (asynch_interrupt){
|
||||
subsumption_queue.clear();
|
||||
bwdsub_assigns = trail.size();
|
||||
break; }
|
||||
|
||||
// Check top-level assignments by creating a dummy clause and placing it in the queue:
|
||||
if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){
|
||||
Lit l = trail[bwdsub_assigns++];
|
||||
ca[bwdsub_tmpunit][0] = l;
|
||||
ca[bwdsub_tmpunit].calcAbstraction();
|
||||
subsumption_queue.insert(bwdsub_tmpunit); }
|
||||
|
||||
CRef cr = subsumption_queue.peek(); subsumption_queue.pop();
|
||||
Clause& c = ca[cr];
|
||||
|
||||
if (c.mark()) continue;
|
||||
|
||||
if (verbose && verbosity >= 2 && cnt++ % 1000 == 0)
|
||||
printf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals);
|
||||
|
||||
assert(c.size() > 1 || value(c[0]) == l_True); // Unit-clauses should have been propagated before this point.
|
||||
|
||||
// Find best variable to scan:
|
||||
Var best = var(c[0]);
|
||||
for (int i = 1; i < c.size(); i++)
|
||||
if (occurs[var(c[i])].size() < occurs[best].size())
|
||||
best = var(c[i]);
|
||||
|
||||
// Search all candidates:
|
||||
vec<CRef>& _cs = occurs.lookup(best);
|
||||
CRef* cs = (CRef*)_cs;
|
||||
|
||||
for (int j = 0; j < _cs.size(); j++)
|
||||
if (c.mark())
|
||||
break;
|
||||
else if (!ca[cs[j]].mark() && cs[j] != cr && (subsumption_lim == -1 || ca[cs[j]].size() < subsumption_lim)){
|
||||
Lit l = c.subsumes(ca[cs[j]]);
|
||||
|
||||
if (l == lit_Undef)
|
||||
subsumed++, removeClause(cs[j]);
|
||||
else if (l != lit_Error){
|
||||
deleted_literals++;
|
||||
|
||||
if (!strengthenClause(cs[j], ~l))
|
||||
return false;
|
||||
|
||||
// Did current candidate get deleted from cs? Then check candidate at index j again:
|
||||
if (var(l) == best)
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SimpSolver::asymm(Var v, CRef cr)
|
||||
{
|
||||
Clause& c = ca[cr];
|
||||
assert(decisionLevel() == 0);
|
||||
|
||||
if (c.mark() || satisfied(c)) return true;
|
||||
|
||||
trail_lim.push(trail.size());
|
||||
Lit l = lit_Undef;
|
||||
for (int i = 0; i < c.size(); i++)
|
||||
if (var(c[i]) != v && value(c[i]) != l_False)
|
||||
uncheckedEnqueue(~c[i]);
|
||||
else
|
||||
l = c[i];
|
||||
|
||||
if (propagate() != CRef_Undef){
|
||||
cancelUntil(0);
|
||||
asymm_lits++;
|
||||
if (!strengthenClause(cr, l))
|
||||
return false;
|
||||
}else
|
||||
cancelUntil(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SimpSolver::asymmVar(Var v)
|
||||
{
|
||||
assert(use_simplification);
|
||||
|
||||
const vec<CRef>& cls = occurs.lookup(v);
|
||||
|
||||
if (value(v) != l_Undef || cls.size() == 0)
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < cls.size(); i++)
|
||||
if (!asymm(v, cls[i]))
|
||||
return false;
|
||||
|
||||
return backwardSubsumptionCheck();
|
||||
}
|
||||
|
||||
|
||||
static void mkElimClause(vec<uint32_t>& elimclauses, Lit x)
|
||||
{
|
||||
elimclauses.push(toInt(x));
|
||||
elimclauses.push(1);
|
||||
}
|
||||
|
||||
|
||||
static void mkElimClause(vec<uint32_t>& elimclauses, Var v, Clause& c)
|
||||
{
|
||||
int first = elimclauses.size();
|
||||
int v_pos = -1;
|
||||
|
||||
// Copy clause to elimclauses-vector. Remember position where the
|
||||
// variable 'v' occurs:
|
||||
for (int i = 0; i < c.size(); i++){
|
||||
elimclauses.push(toInt(c[i]));
|
||||
if (var(c[i]) == v)
|
||||
v_pos = i + first;
|
||||
}
|
||||
assert(v_pos != -1);
|
||||
|
||||
// Swap the first literal with the 'v' literal, so that the literal
|
||||
// containing 'v' will occur first in the clause:
|
||||
uint32_t tmp = elimclauses[v_pos];
|
||||
elimclauses[v_pos] = elimclauses[first];
|
||||
elimclauses[first] = tmp;
|
||||
|
||||
// Store the length of the clause last:
|
||||
elimclauses.push(c.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool SimpSolver::eliminateVar(Var v)
|
||||
{
|
||||
assert(!frozen[v]);
|
||||
assert(!isEliminated(v));
|
||||
assert(value(v) == l_Undef);
|
||||
|
||||
// Split the occurrences into positive and negative:
|
||||
//
|
||||
const vec<CRef>& cls = occurs.lookup(v);
|
||||
vec<CRef> pos, neg;
|
||||
for (int i = 0; i < cls.size(); i++)
|
||||
(find(ca[cls[i]], mkLit(v)) ? pos : neg).push(cls[i]);
|
||||
|
||||
// Check wether the increase in number of clauses stays within the allowed ('grow'). Moreover, no
|
||||
// clause must exceed the limit on the maximal clause size (if it is set):
|
||||
//
|
||||
int cnt = 0;
|
||||
int clause_size = 0;
|
||||
|
||||
for (int i = 0; i < pos.size(); i++)
|
||||
for (int j = 0; j < neg.size(); j++)
|
||||
if (merge(ca[pos[i]], ca[neg[j]], v, clause_size) &&
|
||||
(++cnt > cls.size() + grow || (clause_lim != -1 && clause_size > clause_lim)))
|
||||
return true;
|
||||
|
||||
// Delete and store old clauses:
|
||||
eliminated[v] = true;
|
||||
setDecisionVar(v, false);
|
||||
eliminated_vars++;
|
||||
|
||||
if (pos.size() > neg.size()){
|
||||
for (int i = 0; i < neg.size(); i++)
|
||||
mkElimClause(elimclauses, v, ca[neg[i]]);
|
||||
mkElimClause(elimclauses, mkLit(v));
|
||||
}else{
|
||||
for (int i = 0; i < pos.size(); i++)
|
||||
mkElimClause(elimclauses, v, ca[pos[i]]);
|
||||
mkElimClause(elimclauses, ~mkLit(v));
|
||||
}
|
||||
|
||||
for (int i = 0; i < cls.size(); i++)
|
||||
removeClause(cls[i]);
|
||||
|
||||
// Produce clauses in cross product:
|
||||
vec<Lit>& resolvent = add_tmp;
|
||||
for (int i = 0; i < pos.size(); i++)
|
||||
for (int j = 0; j < neg.size(); j++)
|
||||
if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent))
|
||||
return false;
|
||||
|
||||
// Free occurs list for this variable:
|
||||
occurs[v].clear(true);
|
||||
|
||||
// Free watchers lists for this variable, if possible:
|
||||
if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true);
|
||||
if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true);
|
||||
|
||||
return backwardSubsumptionCheck();
|
||||
}
|
||||
|
||||
|
||||
bool SimpSolver::substitute(Var v, Lit x)
|
||||
{
|
||||
assert(!frozen[v]);
|
||||
assert(!isEliminated(v));
|
||||
assert(value(v) == l_Undef);
|
||||
|
||||
if (!ok) return false;
|
||||
|
||||
eliminated[v] = true;
|
||||
setDecisionVar(v, false);
|
||||
const vec<CRef>& cls = occurs.lookup(v);
|
||||
|
||||
vec<Lit>& subst_clause = add_tmp;
|
||||
for (int i = 0; i < cls.size(); i++){
|
||||
Clause& c = ca[cls[i]];
|
||||
|
||||
subst_clause.clear();
|
||||
for (int j = 0; j < c.size(); j++){
|
||||
Lit p = c[j];
|
||||
subst_clause.push(var(p) == v ? x ^ sign(p) : p);
|
||||
}
|
||||
|
||||
removeClause(cls[i]);
|
||||
|
||||
if (!addClause_(subst_clause))
|
||||
return ok = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SimpSolver::extendModel()
|
||||
{
|
||||
int i, j;
|
||||
Lit x;
|
||||
|
||||
for (i = elimclauses.size()-1; i > 0; i -= j){
|
||||
for (j = elimclauses[i--]; j > 1; j--, i--)
|
||||
if (modelValue(toLit(elimclauses[i])) != l_False)
|
||||
goto next;
|
||||
|
||||
x = toLit(elimclauses[i]);
|
||||
model[var(x)] = lbool(!sign(x));
|
||||
next:;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SimpSolver::eliminate(bool turn_off_elim)
|
||||
{
|
||||
if (!simplify())
|
||||
return false;
|
||||
else if (!use_simplification)
|
||||
return true;
|
||||
|
||||
// Main simplification loop:
|
||||
//
|
||||
while (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0){
|
||||
|
||||
gatherTouchedClauses();
|
||||
// printf(" ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns);
|
||||
if ((subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()) &&
|
||||
!backwardSubsumptionCheck(true)){
|
||||
ok = false; goto cleanup; }
|
||||
|
||||
// Empty elim_heap and return immediately on user-interrupt:
|
||||
if (asynch_interrupt){
|
||||
assert(bwdsub_assigns == trail.size());
|
||||
assert(subsumption_queue.size() == 0);
|
||||
assert(n_touched == 0);
|
||||
elim_heap.clear();
|
||||
goto cleanup; }
|
||||
|
||||
// printf(" ## (time = %6.2f s) ELIM: vars = %d\n", cpuTime(), elim_heap.size());
|
||||
for (int cnt = 0; !elim_heap.empty(); cnt++){
|
||||
Var elim = elim_heap.removeMin();
|
||||
|
||||
if (asynch_interrupt) break;
|
||||
|
||||
if (isEliminated(elim) || value(elim) != l_Undef) continue;
|
||||
|
||||
if (verbosity >= 2 && cnt % 100 == 0)
|
||||
printf("elimination left: %10d\r", elim_heap.size());
|
||||
|
||||
if (use_asymm){
|
||||
// Temporarily freeze variable. Otherwise, it would immediately end up on the queue again:
|
||||
bool was_frozen = frozen[elim];
|
||||
frozen[elim] = true;
|
||||
if (!asymmVar(elim)){
|
||||
ok = false; goto cleanup; }
|
||||
frozen[elim] = was_frozen; }
|
||||
|
||||
// At this point, the variable may have been set by assymetric branching, so check it
|
||||
// again. Also, don't eliminate frozen variables:
|
||||
if (use_elim && value(elim) == l_Undef && !frozen[elim] && !eliminateVar(elim)){
|
||||
ok = false; goto cleanup; }
|
||||
|
||||
checkGarbage(simp_garbage_frac);
|
||||
}
|
||||
|
||||
assert(subsumption_queue.size() == 0);
|
||||
}
|
||||
cleanup:
|
||||
|
||||
// If no more simplification is needed, free all simplification-related data structures:
|
||||
if (turn_off_elim){
|
||||
touched .clear(true);
|
||||
occurs .clear(true);
|
||||
n_occ .clear(true);
|
||||
elim_heap.clear(true);
|
||||
subsumption_queue.clear(true);
|
||||
|
||||
use_simplification = false;
|
||||
remove_satisfied = true;
|
||||
ca.extra_clause_field = false;
|
||||
|
||||
// Force full cleanup (this is safe and desirable since it only happens once):
|
||||
rebuildOrderHeap();
|
||||
garbageCollect();
|
||||
}else{
|
||||
// Cheaper cleanup:
|
||||
cleanUpClauses(); // TODO: can we make 'cleanUpClauses()' not be linear in the problem size somehow?
|
||||
checkGarbage();
|
||||
}
|
||||
|
||||
if (verbosity >= 1 && elimclauses.size() > 0)
|
||||
printf("| Eliminated clauses: %10.2f Mb |\n",
|
||||
double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024));
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
void SimpSolver::cleanUpClauses()
|
||||
{
|
||||
occurs.cleanAll();
|
||||
int i,j;
|
||||
for (i = j = 0; i < clauses.size(); i++)
|
||||
if (ca[clauses[i]].mark() == 0)
|
||||
clauses[j++] = clauses[i];
|
||||
clauses.shrink(i - j);
|
||||
}
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Garbage Collection methods:
|
||||
|
||||
|
||||
void SimpSolver::relocAll(ClauseAllocator& to)
|
||||
{
|
||||
if (!use_simplification) return;
|
||||
|
||||
// All occurs lists:
|
||||
//
|
||||
for (int i = 0; i < nVars(); i++){
|
||||
vec<CRef>& cs = occurs[i];
|
||||
for (int j = 0; j < cs.size(); j++)
|
||||
ca.reloc(cs[j], to);
|
||||
}
|
||||
|
||||
// Subsumption queue:
|
||||
//
|
||||
for (int i = 0; i < subsumption_queue.size(); i++)
|
||||
ca.reloc(subsumption_queue[i], to);
|
||||
|
||||
// Temporary clause:
|
||||
//
|
||||
ca.reloc(bwdsub_tmpunit, to);
|
||||
}
|
||||
|
||||
|
||||
void SimpSolver::garbageCollect()
|
||||
{
|
||||
// Initialize the next region to a size corresponding to the estimated utilization degree. This
|
||||
// is not precise but should avoid some unnecessary reallocations for the new region:
|
||||
ClauseAllocator to(ca.size() - ca.wasted());
|
||||
|
||||
cleanUpClauses();
|
||||
to.extra_clause_field = ca.extra_clause_field; // NOTE: this is important to keep (or lose) the extra fields.
|
||||
relocAll(to);
|
||||
Solver::relocAll(to);
|
||||
if (verbosity >= 2)
|
||||
printf("| Garbage collection: %12d bytes => %12d bytes |\n",
|
||||
ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
|
||||
to.moveTo(ca);
|
||||
}
|
197
contrib/minisat/src/simp/SimpSolver.h
Normal file
197
contrib/minisat/src/simp/SimpSolver.h
Normal file
@@ -0,0 +1,197 @@
|
||||
/************************************************************************************[SimpSolver.h]
|
||||
Copyright (c) 2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_SimpSolver_h
|
||||
#define Minisat_SimpSolver_h
|
||||
|
||||
#include "mtl/Queue.h"
|
||||
#include "core/Solver.h"
|
||||
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
|
||||
class SimpSolver : public Solver {
|
||||
public:
|
||||
// Constructor/Destructor:
|
||||
//
|
||||
SimpSolver();
|
||||
~SimpSolver();
|
||||
|
||||
// Problem specification:
|
||||
//
|
||||
Var newVar (bool polarity = true, bool dvar = true);
|
||||
bool addClause (const vec<Lit>& ps);
|
||||
bool addEmptyClause(); // Add the empty clause to the solver.
|
||||
bool addClause (Lit p); // Add a unit clause to the solver.
|
||||
bool addClause (Lit p, Lit q); // Add a binary clause to the solver.
|
||||
bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
|
||||
bool addClause_( vec<Lit>& ps);
|
||||
bool substitute(Var v, Lit x); // Replace all occurences of v with x (may cause a contradiction).
|
||||
|
||||
// Variable mode:
|
||||
//
|
||||
void setFrozen (Var v, bool b); // If a variable is frozen it will not be eliminated.
|
||||
bool isEliminated(Var v) const;
|
||||
|
||||
// Solving:
|
||||
//
|
||||
bool solve (const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
|
||||
lbool solveLimited(const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
|
||||
bool solve ( bool do_simp = true, bool turn_off_simp = false);
|
||||
bool solve (Lit p , bool do_simp = true, bool turn_off_simp = false);
|
||||
bool solve (Lit p, Lit q, bool do_simp = true, bool turn_off_simp = false);
|
||||
bool solve (Lit p, Lit q, Lit r, bool do_simp = true, bool turn_off_simp = false);
|
||||
bool eliminate (bool turn_off_elim = false); // Perform variable elimination based simplification.
|
||||
|
||||
// Memory managment:
|
||||
//
|
||||
virtual void garbageCollect();
|
||||
|
||||
|
||||
// Generate a (possibly simplified) DIMACS file:
|
||||
//
|
||||
#if 0
|
||||
void toDimacs (const char* file, const vec<Lit>& assumps);
|
||||
void toDimacs (const char* file);
|
||||
void toDimacs (const char* file, Lit p);
|
||||
void toDimacs (const char* file, Lit p, Lit q);
|
||||
void toDimacs (const char* file, Lit p, Lit q, Lit r);
|
||||
#endif
|
||||
|
||||
// Mode of operation:
|
||||
//
|
||||
int grow; // Allow a variable elimination step to grow by a number of clauses (default to zero).
|
||||
int clause_lim; // Variables are not eliminated if it produces a resolvent with a length above this limit.
|
||||
// -1 means no limit.
|
||||
int subsumption_lim; // Do not check if subsumption against a clause larger than this. -1 means no limit.
|
||||
double simp_garbage_frac; // A different limit for when to issue a GC during simplification (Also see 'garbage_frac').
|
||||
|
||||
bool use_asymm; // Shrink clauses by asymmetric branching.
|
||||
bool use_rcheck; // Check if a clause is already implied. Prett costly, and subsumes subsumptions :)
|
||||
bool use_elim; // Perform variable elimination.
|
||||
|
||||
// Statistics:
|
||||
//
|
||||
int merges;
|
||||
int asymm_lits;
|
||||
int eliminated_vars;
|
||||
|
||||
protected:
|
||||
|
||||
// Helper structures:
|
||||
//
|
||||
struct ElimLt {
|
||||
const vec<int>& n_occ;
|
||||
explicit ElimLt(const vec<int>& no) : n_occ(no) {}
|
||||
|
||||
// TODO: are 64-bit operations here noticably bad on 32-bit platforms? Could use a saturating
|
||||
// 32-bit implementation instead then, but this will have to do for now.
|
||||
uint64_t cost (Var x) const { return (uint64_t)n_occ[toInt(mkLit(x))] * (uint64_t)n_occ[toInt(~mkLit(x))]; }
|
||||
bool operator()(Var x, Var y) const { return cost(x) < cost(y); }
|
||||
|
||||
// TODO: investigate this order alternative more.
|
||||
// bool operator()(Var x, Var y) const {
|
||||
// int c_x = cost(x);
|
||||
// int c_y = cost(y);
|
||||
// return c_x < c_y || c_x == c_y && x < y; }
|
||||
};
|
||||
|
||||
struct ClauseDeleted {
|
||||
const ClauseAllocator& ca;
|
||||
explicit ClauseDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
|
||||
bool operator()(const CRef& cr) const { return ca[cr].mark() == 1; } };
|
||||
|
||||
// Solver state:
|
||||
//
|
||||
int elimorder;
|
||||
bool use_simplification;
|
||||
vec<uint32_t> elimclauses;
|
||||
vec<char> touched;
|
||||
OccLists<Var, vec<CRef>, ClauseDeleted>
|
||||
occurs;
|
||||
vec<int> n_occ;
|
||||
Heap<ElimLt> elim_heap;
|
||||
Queue<CRef> subsumption_queue;
|
||||
vec<char> frozen;
|
||||
vec<char> eliminated;
|
||||
int bwdsub_assigns;
|
||||
int n_touched;
|
||||
|
||||
// Temporaries:
|
||||
//
|
||||
CRef bwdsub_tmpunit;
|
||||
|
||||
// Main internal methods:
|
||||
//
|
||||
lbool solve_ (bool do_simp = true, bool turn_off_simp = false);
|
||||
bool asymm (Var v, CRef cr);
|
||||
bool asymmVar (Var v);
|
||||
void updateElimHeap (Var v);
|
||||
void gatherTouchedClauses ();
|
||||
bool merge (const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause);
|
||||
bool merge (const Clause& _ps, const Clause& _qs, Var v, int& size);
|
||||
bool backwardSubsumptionCheck (bool verbose = false);
|
||||
bool eliminateVar (Var v);
|
||||
void extendModel ();
|
||||
|
||||
void removeClause (CRef cr);
|
||||
bool strengthenClause (CRef cr, Lit l);
|
||||
void cleanUpClauses ();
|
||||
bool implied (const vec<Lit>& c);
|
||||
void relocAll (ClauseAllocator& to);
|
||||
};
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// Implementation of inline methods:
|
||||
|
||||
|
||||
inline bool SimpSolver::isEliminated (Var v) const { return eliminated[v]; }
|
||||
inline void SimpSolver::updateElimHeap(Var v) {
|
||||
assert(use_simplification);
|
||||
// if (!frozen[v] && !isEliminated(v) && value(v) == l_Undef)
|
||||
if (elim_heap.inHeap(v) || (!frozen[v] && !isEliminated(v) && value(v) == l_Undef))
|
||||
elim_heap.update(v); }
|
||||
|
||||
|
||||
inline bool SimpSolver::addClause (const vec<Lit>& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); }
|
||||
inline bool SimpSolver::addEmptyClause() { add_tmp.clear(); return addClause_(add_tmp); }
|
||||
inline bool SimpSolver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
|
||||
inline bool SimpSolver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
|
||||
inline bool SimpSolver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
|
||||
inline void SimpSolver::setFrozen (Var v, bool b) { frozen[v] = (char)b; if (use_simplification && !b) { updateElimHeap(v); } }
|
||||
|
||||
inline bool SimpSolver::solve ( bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); return solve_(do_simp, turn_off_simp) == l_True; }
|
||||
inline bool SimpSolver::solve (Lit p , bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_(do_simp, turn_off_simp) == l_True; }
|
||||
inline bool SimpSolver::solve (Lit p, Lit q, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_(do_simp, turn_off_simp) == l_True; }
|
||||
inline bool SimpSolver::solve (Lit p, Lit q, Lit r, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_(do_simp, turn_off_simp) == l_True; }
|
||||
inline bool SimpSolver::solve (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
|
||||
budgetOff(); assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp) == l_True; }
|
||||
|
||||
inline lbool SimpSolver::solveLimited (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
|
||||
assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp); }
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
4
contrib/minisat/src/utils/Makefile
Normal file
4
contrib/minisat/src/utils/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
EXEC = system_test
|
||||
DEPDIR = mtl
|
||||
|
||||
include $(MROOT)/mtl/template.mk
|
91
contrib/minisat/src/utils/Options.cc
Normal file
91
contrib/minisat/src/utils/Options.cc
Normal file
@@ -0,0 +1,91 @@
|
||||
/**************************************************************************************[Options.cc]
|
||||
Copyright (c) 2008-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include "mtl/Sort.h"
|
||||
#include "utils/Options.h"
|
||||
#include "utils/ParseUtils.h"
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
void Minisat::parseOptions(int& argc, char** argv, bool strict)
|
||||
{
|
||||
int i, j;
|
||||
for (i = j = 1; i < argc; i++){
|
||||
const char* str = argv[i];
|
||||
if (match(str, "--") && match(str, Option::getHelpPrefixString()) && match(str, "help")){
|
||||
if (*str == '\0')
|
||||
printUsageAndExit(argc, argv);
|
||||
else if (match(str, "-verb"))
|
||||
printUsageAndExit(argc, argv, true);
|
||||
} else {
|
||||
bool parsed_ok = false;
|
||||
|
||||
for (int k = 0; !parsed_ok && k < Option::getOptionList().size(); k++){
|
||||
parsed_ok = Option::getOptionList()[k]->parse(argv[i]);
|
||||
|
||||
// fprintf(stderr, "checking %d: %s against flag <%s> (%s)\n", i, argv[i], Option::getOptionList()[k]->name, parsed_ok ? "ok" : "skip");
|
||||
}
|
||||
|
||||
if (!parsed_ok)
|
||||
if (strict && match(argv[i], "-"))
|
||||
fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()), exit(1);
|
||||
else
|
||||
argv[j++] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
argc -= (i - j);
|
||||
}
|
||||
|
||||
|
||||
void Minisat::setUsageHelp (const char* str){ Option::getUsageString() = str; }
|
||||
void Minisat::setHelpPrefixStr (const char* str){ Option::getHelpPrefixString() = str; }
|
||||
void Minisat::printUsageAndExit (int argc, char** argv, bool verbose)
|
||||
{
|
||||
const char* usage = Option::getUsageString();
|
||||
if (usage != NULL)
|
||||
fprintf(stderr, usage, argv[0]);
|
||||
|
||||
sort(Option::getOptionList(), Option::OptionLt());
|
||||
|
||||
const char* prev_cat = NULL;
|
||||
const char* prev_type = NULL;
|
||||
|
||||
for (int i = 0; i < Option::getOptionList().size(); i++){
|
||||
const char* cat = Option::getOptionList()[i]->category;
|
||||
const char* type = Option::getOptionList()[i]->type_name;
|
||||
|
||||
if (cat != prev_cat)
|
||||
fprintf(stderr, "\n%s OPTIONS:\n\n", cat);
|
||||
else if (type != prev_type)
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
Option::getOptionList()[i]->help(verbose);
|
||||
|
||||
prev_cat = Option::getOptionList()[i]->category;
|
||||
prev_type = Option::getOptionList()[i]->type_name;
|
||||
}
|
||||
|
||||
fprintf(stderr, "\nHELP OPTIONS:\n\n");
|
||||
fprintf(stderr, " --%shelp Print help message.\n", Option::getHelpPrefixString());
|
||||
fprintf(stderr, " --%shelp-verb Print verbose help message.\n", Option::getHelpPrefixString());
|
||||
fprintf(stderr, "\n");
|
||||
exit(0);
|
||||
}
|
||||
|
386
contrib/minisat/src/utils/Options.h
Normal file
386
contrib/minisat/src/utils/Options.h
Normal file
@@ -0,0 +1,386 @@
|
||||
/***************************************************************************************[Options.h]
|
||||
Copyright (c) 2008-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_Options_h
|
||||
#define Minisat_Options_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mtl/IntTypes.h"
|
||||
#include "mtl/Vec.h"
|
||||
#include "utils/ParseUtils.h"
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//==================================================================================================
|
||||
// Top-level option parse/help functions:
|
||||
|
||||
|
||||
extern void parseOptions (int& argc, char** argv, bool strict = false);
|
||||
extern void printUsageAndExit(int argc, char** argv, bool verbose = false);
|
||||
extern void setUsageHelp (const char* str);
|
||||
extern void setHelpPrefixStr (const char* str);
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
// Options is an abstract class that gives the interface for all types options:
|
||||
|
||||
|
||||
class Option
|
||||
{
|
||||
protected:
|
||||
const char* name;
|
||||
const char* description;
|
||||
const char* category;
|
||||
const char* type_name;
|
||||
|
||||
static vec<Option*>& getOptionList () { static vec<Option*> options; return options; }
|
||||
static const char*& getUsageString() { static const char* usage_str; return usage_str; }
|
||||
static const char*& getHelpPrefixString() { static const char* help_prefix_str = ""; return help_prefix_str; }
|
||||
|
||||
struct OptionLt {
|
||||
bool operator()(const Option* x, const Option* y) {
|
||||
int test1 = strcmp(x->category, y->category);
|
||||
return test1 < 0 || test1 == 0 && strcmp(x->type_name, y->type_name) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
Option(const char* name_,
|
||||
const char* desc_,
|
||||
const char* cate_,
|
||||
const char* type_) :
|
||||
name (name_)
|
||||
, description(desc_)
|
||||
, category (cate_)
|
||||
, type_name (type_)
|
||||
{
|
||||
getOptionList().push(this);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~Option() {}
|
||||
|
||||
virtual bool parse (const char* str) = 0;
|
||||
virtual void help (bool verbose = false) = 0;
|
||||
|
||||
friend void parseOptions (int& argc, char** argv, bool strict);
|
||||
friend void printUsageAndExit (int argc, char** argv, bool verbose);
|
||||
friend void setUsageHelp (const char* str);
|
||||
friend void setHelpPrefixStr (const char* str);
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
// Range classes with specialization for floating types:
|
||||
|
||||
|
||||
struct IntRange {
|
||||
int begin;
|
||||
int end;
|
||||
IntRange(int b, int e) : begin(b), end(e) {}
|
||||
};
|
||||
|
||||
struct Int64Range {
|
||||
int64_t begin;
|
||||
int64_t end;
|
||||
Int64Range(int64_t b, int64_t e) : begin(b), end(e) {}
|
||||
};
|
||||
|
||||
struct DoubleRange {
|
||||
double begin;
|
||||
double end;
|
||||
bool begin_inclusive;
|
||||
bool end_inclusive;
|
||||
DoubleRange(double b, bool binc, double e, bool einc) : begin(b), end(e), begin_inclusive(binc), end_inclusive(einc) {}
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
// Double options:
|
||||
|
||||
|
||||
class DoubleOption : public Option
|
||||
{
|
||||
protected:
|
||||
DoubleRange range;
|
||||
double value;
|
||||
|
||||
public:
|
||||
DoubleOption(const char* c, const char* n, const char* d, double def = double(), DoubleRange r = DoubleRange(-HUGE_VAL, false, HUGE_VAL, false))
|
||||
: Option(n, d, c, "<double>"), range(r), value(def) {
|
||||
// FIXME: set LC_NUMERIC to "C" to make sure that strtof/strtod parses decimal point correctly.
|
||||
}
|
||||
|
||||
operator double (void) const { return value; }
|
||||
operator double& (void) { return value; }
|
||||
DoubleOption& operator=(double x) { value = x; return *this; }
|
||||
|
||||
virtual bool parse(const char* str){
|
||||
const char* span = str;
|
||||
|
||||
if (!match(span, "-") || !match(span, name) || !match(span, "="))
|
||||
return false;
|
||||
|
||||
char* end;
|
||||
double tmp = strtod(span, &end);
|
||||
|
||||
if (end == NULL)
|
||||
return false;
|
||||
else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){
|
||||
fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
|
||||
exit(1);
|
||||
}else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){
|
||||
fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
|
||||
exit(1); }
|
||||
|
||||
value = tmp;
|
||||
// fprintf(stderr, "READ VALUE: %g\n", value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void help (bool verbose = false){
|
||||
fprintf(stderr, " -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n",
|
||||
name, type_name,
|
||||
range.begin_inclusive ? '[' : '(',
|
||||
range.begin,
|
||||
range.end,
|
||||
range.end_inclusive ? ']' : ')',
|
||||
value);
|
||||
if (verbose){
|
||||
fprintf(stderr, "\n %s\n", description);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
// Int options:
|
||||
|
||||
|
||||
class IntOption : public Option
|
||||
{
|
||||
protected:
|
||||
IntRange range;
|
||||
int32_t value;
|
||||
|
||||
public:
|
||||
IntOption(const char* c, const char* n, const char* d, int32_t def = int32_t(), IntRange r = IntRange(INT32_MIN, INT32_MAX))
|
||||
: Option(n, d, c, "<int32>"), range(r), value(def) {}
|
||||
|
||||
operator int32_t (void) const { return value; }
|
||||
operator int32_t& (void) { return value; }
|
||||
IntOption& operator= (int32_t x) { value = x; return *this; }
|
||||
|
||||
virtual bool parse(const char* str){
|
||||
const char* span = str;
|
||||
|
||||
if (!match(span, "-") || !match(span, name) || !match(span, "="))
|
||||
return false;
|
||||
|
||||
char* end;
|
||||
int32_t tmp = strtol(span, &end, 10);
|
||||
|
||||
if (end == NULL)
|
||||
return false;
|
||||
else if (tmp > range.end){
|
||||
fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
|
||||
exit(1);
|
||||
}else if (tmp < range.begin){
|
||||
fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
|
||||
exit(1); }
|
||||
|
||||
value = tmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void help (bool verbose = false){
|
||||
fprintf(stderr, " -%-12s = %-8s [", name, type_name);
|
||||
if (range.begin == INT32_MIN)
|
||||
fprintf(stderr, "imin");
|
||||
else
|
||||
fprintf(stderr, "%4d", range.begin);
|
||||
|
||||
fprintf(stderr, " .. ");
|
||||
if (range.end == INT32_MAX)
|
||||
fprintf(stderr, "imax");
|
||||
else
|
||||
fprintf(stderr, "%4d", range.end);
|
||||
|
||||
fprintf(stderr, "] (default: %d)\n", value);
|
||||
if (verbose){
|
||||
fprintf(stderr, "\n %s\n", description);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Leave this out for visual C++ until Microsoft implements C99 and gets support for strtoll.
|
||||
#ifndef _MSC_VER
|
||||
|
||||
class Int64Option : public Option
|
||||
{
|
||||
protected:
|
||||
Int64Range range;
|
||||
int64_t value;
|
||||
|
||||
public:
|
||||
Int64Option(const char* c, const char* n, const char* d, int64_t def = int64_t(), Int64Range r = Int64Range(INT64_MIN, INT64_MAX))
|
||||
: Option(n, d, c, "<int64>"), range(r), value(def) {}
|
||||
|
||||
operator int64_t (void) const { return value; }
|
||||
operator int64_t& (void) { return value; }
|
||||
Int64Option& operator= (int64_t x) { value = x; return *this; }
|
||||
|
||||
virtual bool parse(const char* str){
|
||||
const char* span = str;
|
||||
|
||||
if (!match(span, "-") || !match(span, name) || !match(span, "="))
|
||||
return false;
|
||||
|
||||
char* end;
|
||||
int64_t tmp = strtoll(span, &end, 10);
|
||||
|
||||
if (end == NULL)
|
||||
return false;
|
||||
else if (tmp > range.end){
|
||||
fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
|
||||
exit(1);
|
||||
}else if (tmp < range.begin){
|
||||
fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
|
||||
exit(1); }
|
||||
|
||||
value = tmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void help (bool verbose = false){
|
||||
fprintf(stderr, " -%-12s = %-8s [", name, type_name);
|
||||
if (range.begin == INT64_MIN)
|
||||
fprintf(stderr, "imin");
|
||||
else
|
||||
fprintf(stderr, "%4"PRIi64, range.begin);
|
||||
|
||||
fprintf(stderr, " .. ");
|
||||
if (range.end == INT64_MAX)
|
||||
fprintf(stderr, "imax");
|
||||
else
|
||||
fprintf(stderr, "%4"PRIi64, range.end);
|
||||
|
||||
fprintf(stderr, "] (default: %"PRIi64")\n", value);
|
||||
if (verbose){
|
||||
fprintf(stderr, "\n %s\n", description);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
// String option:
|
||||
|
||||
|
||||
class StringOption : public Option
|
||||
{
|
||||
const char* value;
|
||||
public:
|
||||
StringOption(const char* c, const char* n, const char* d, const char* def = NULL)
|
||||
: Option(n, d, c, "<string>"), value(def) {}
|
||||
|
||||
operator const char* (void) const { return value; }
|
||||
operator const char*& (void) { return value; }
|
||||
StringOption& operator= (const char* x) { value = x; return *this; }
|
||||
|
||||
virtual bool parse(const char* str){
|
||||
const char* span = str;
|
||||
|
||||
if (!match(span, "-") || !match(span, name) || !match(span, "="))
|
||||
return false;
|
||||
|
||||
value = span;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void help (bool verbose = false){
|
||||
fprintf(stderr, " -%-10s = %8s\n", name, type_name);
|
||||
if (verbose){
|
||||
fprintf(stderr, "\n %s\n", description);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
// Bool option:
|
||||
|
||||
|
||||
class BoolOption : public Option
|
||||
{
|
||||
bool value;
|
||||
|
||||
public:
|
||||
BoolOption(const char* c, const char* n, const char* d, bool v)
|
||||
: Option(n, d, c, "<bool>"), value(v) {}
|
||||
|
||||
operator bool (void) const { return value; }
|
||||
operator bool& (void) { return value; }
|
||||
BoolOption& operator=(bool b) { value = b; return *this; }
|
||||
|
||||
virtual bool parse(const char* str){
|
||||
const char* span = str;
|
||||
|
||||
if (match(span, "-")){
|
||||
bool b = !match(span, "no-");
|
||||
|
||||
if (strcmp(span, name) == 0){
|
||||
value = b;
|
||||
return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void help (bool verbose = false){
|
||||
|
||||
fprintf(stderr, " -%s, -no-%s", name, name);
|
||||
|
||||
for (uint32_t i = 0; i < 32 - strlen(name)*2; i++)
|
||||
fprintf(stderr, " ");
|
||||
|
||||
fprintf(stderr, " ");
|
||||
fprintf(stderr, "(default: %s)\n", value ? "on" : "off");
|
||||
if (verbose){
|
||||
fprintf(stderr, "\n %s\n", description);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
122
contrib/minisat/src/utils/ParseUtils.h
Normal file
122
contrib/minisat/src/utils/ParseUtils.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/************************************************************************************[ParseUtils.h]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_ParseUtils_h
|
||||
#define Minisat_ParseUtils_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// A simple buffered character stream class:
|
||||
|
||||
static const int buffer_size = 1048576;
|
||||
|
||||
|
||||
class StreamBuffer {
|
||||
gzFile in;
|
||||
unsigned char buf[buffer_size];
|
||||
int pos;
|
||||
int size;
|
||||
|
||||
void assureLookahead() {
|
||||
if (pos >= size) {
|
||||
pos = 0;
|
||||
size = gzread(in, buf, sizeof(buf)); } }
|
||||
|
||||
public:
|
||||
explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0) { assureLookahead(); }
|
||||
|
||||
int operator * () const { return (pos >= size) ? EOF : buf[pos]; }
|
||||
void operator ++ () { pos++; assureLookahead(); }
|
||||
int position () const { return pos; }
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// End-of-file detection functions for StreamBuffer and char*:
|
||||
|
||||
|
||||
static inline bool isEof(StreamBuffer& in) { return *in == EOF; }
|
||||
static inline bool isEof(const char* in) { return *in == '\0'; }
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Generic parse functions parametrized over the input-stream type.
|
||||
|
||||
|
||||
template<class B>
|
||||
static void skipWhitespace(B& in) {
|
||||
while ((*in >= 9 && *in <= 13) || *in == 32)
|
||||
++in; }
|
||||
|
||||
|
||||
template<class B>
|
||||
static void skipLine(B& in) {
|
||||
for (;;){
|
||||
if (isEof(in)) return;
|
||||
if (*in == '\n') { ++in; return; }
|
||||
++in; } }
|
||||
|
||||
|
||||
template<class B>
|
||||
static int parseInt(B& in) {
|
||||
int val = 0;
|
||||
bool neg = false;
|
||||
skipWhitespace(in);
|
||||
if (*in == '-') neg = true, ++in;
|
||||
else if (*in == '+') ++in;
|
||||
if (*in < '0' || *in > '9') fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
|
||||
while (*in >= '0' && *in <= '9')
|
||||
val = val*10 + (*in - '0'),
|
||||
++in;
|
||||
return neg ? -val : val; }
|
||||
|
||||
|
||||
// String matching: in case of a match the input iterator will be advanced the corresponding
|
||||
// number of characters.
|
||||
template<class B>
|
||||
static bool match(B& in, const char* str) {
|
||||
int i;
|
||||
for (i = 0; str[i] != '\0'; i++)
|
||||
if (in[i] != str[i])
|
||||
return false;
|
||||
|
||||
in += i;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// String matching: consumes characters eagerly, but does not require random access iterator.
|
||||
template<class B>
|
||||
static bool eagerMatch(B& in, const char* str) {
|
||||
for (; *str != '\0'; ++str, ++in)
|
||||
if (*str != *in)
|
||||
return false;
|
||||
return true; }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
}
|
||||
|
||||
#endif
|
95
contrib/minisat/src/utils/System.cc
Normal file
95
contrib/minisat/src/utils/System.cc
Normal file
@@ -0,0 +1,95 @@
|
||||
/***************************************************************************************[System.cc]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include "utils/System.h"
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace Minisat;
|
||||
|
||||
// TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and
|
||||
// one for reading the current virtual memory size.
|
||||
|
||||
static inline int memReadStat(int field)
|
||||
{
|
||||
char name[256];
|
||||
pid_t pid = getpid();
|
||||
int value;
|
||||
|
||||
sprintf(name, "/proc/%d/statm", pid);
|
||||
FILE* in = fopen(name, "rb");
|
||||
if (in == NULL) return 0;
|
||||
|
||||
for (; field >= 0; field--)
|
||||
if (fscanf(in, "%d", &value) != 1)
|
||||
printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1);
|
||||
fclose(in);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static inline int memReadPeak(void)
|
||||
{
|
||||
char name[256];
|
||||
pid_t pid = getpid();
|
||||
|
||||
sprintf(name, "/proc/%d/status", pid);
|
||||
FILE* in = fopen(name, "rb");
|
||||
if (in == NULL) return 0;
|
||||
|
||||
// Find the correct line, beginning with "VmPeak:":
|
||||
int peak_kb = 0;
|
||||
while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1)
|
||||
while (!feof(in) && fgetc(in) != '\n')
|
||||
;
|
||||
fclose(in);
|
||||
|
||||
return peak_kb;
|
||||
}
|
||||
|
||||
double Minisat::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); }
|
||||
double Minisat::memUsedPeak() {
|
||||
double peak = memReadPeak() / 1024;
|
||||
return peak == 0 ? memUsed() : peak; }
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
double Minisat::memUsed(void) {
|
||||
struct rusage ru;
|
||||
getrusage(RUSAGE_SELF, &ru);
|
||||
return (double)ru.ru_maxrss / 1024; }
|
||||
double MiniSat::memUsedPeak(void) { return memUsed(); }
|
||||
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
#include <malloc/malloc.h>
|
||||
|
||||
double Minisat::memUsed(void) {
|
||||
malloc_statistics_t t;
|
||||
malloc_zone_statistics(NULL, &t);
|
||||
return (double)t.max_size_in_use / (1024*1024); }
|
||||
|
||||
#else
|
||||
double Minisat::memUsed() {
|
||||
return 0; }
|
||||
#endif
|
60
contrib/minisat/src/utils/System.h
Normal file
60
contrib/minisat/src/utils/System.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/****************************************************************************************[System.h]
|
||||
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
||||
Copyright (c) 2007-2010, Niklas Sorensson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#ifndef Minisat_System_h
|
||||
#define Minisat_System_h
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <fpu_control.h>
|
||||
#endif
|
||||
|
||||
#include "mtl/IntTypes.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace Minisat {
|
||||
|
||||
static inline double cpuTime(void); // CPU-time in seconds.
|
||||
extern double memUsed(); // Memory in mega bytes (returns 0 for unsupported architectures).
|
||||
extern double memUsedPeak(); // Peak-memory in mega bytes (returns 0 for unsupported architectures).
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Implementation of inline functions:
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <time.h>
|
||||
|
||||
static inline double Minisat::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; }
|
||||
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static inline double Minisat::cpuTime(void) {
|
||||
struct rusage ru;
|
||||
getrusage(RUSAGE_SELF, &ru);
|
||||
return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
36
contrib/mongoc/SConscript
Normal file
36
contrib/mongoc/SConscript
Normal file
@@ -0,0 +1,36 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
Import('globalEnv')
|
||||
|
||||
env = globalEnv.Clone()
|
||||
|
||||
env['MONGOC_1_13_1_PATH'] = os.path.join(env['MONGOCPATH'], 'mongo-c-driver-1.13.1')
|
||||
|
||||
cmake_build_path = os.path.join(env['MONGOC_LIB_PATH'], 'cmake_build')
|
||||
|
||||
if not os.path.exists(cmake_build_path):
|
||||
os.makedirs(cmake_build_path)
|
||||
|
||||
if not os.path.exists(env["MONGOC_LIB_PATH"]):
|
||||
os.makedirs(env["MONGOC_LIB_PATH"])
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
||||
os.chdir(cmake_build_path)
|
||||
|
||||
cmakeCall = "cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF "
|
||||
cmakeCall += "-DCMAKE_INSTALL_PREFIX=" + env["MONGOC_LIB_PATH"] + " "
|
||||
cmakeCall += env["MONGOC_1_13_1_PATH"]
|
||||
|
||||
print(cmakeCall)
|
||||
|
||||
os.system(cmakeCall)
|
||||
|
||||
os.system("make")
|
||||
|
||||
os.system("make install")
|
||||
|
||||
os.chdir(cwd)
|
||||
|
||||
|
361
contrib/mongoc/mongo-c-driver-1.13.1/CMakeLists.txt
Normal file
361
contrib/mongoc/mongo-c-driver-1.13.1/CMakeLists.txt
Normal file
@@ -0,0 +1,361 @@
|
||||
cmake_minimum_required (VERSION 3.1)
|
||||
|
||||
# Used in MaintainerFlags.cmake to silence errors while testing configs.
|
||||
set (MESSAGES_ENABLED 1)
|
||||
|
||||
function (message)
|
||||
list (GET ARGV 0 MessageType)
|
||||
if (MESSAGES_ENABLED)
|
||||
list (REMOVE_AT ARGV 0)
|
||||
_message (${MessageType} "${ARGV}")
|
||||
endif ()
|
||||
endfunction ()
|
||||
|
||||
set (ENABLE_SSL AUTO CACHE STRING
|
||||
"Enable TLS connections and SCRAM-SHA-1 authentication. Options are
|
||||
\"DARWIN\" to use Apple's Secure Transport, \"WINDOWS\" to use Windows
|
||||
Secure Channel, \"OPENSSL\", \"LIBRESSL\", \"AUTO\",\ or \"OFF\". These options are
|
||||
case-sensitive. The default is \"AUTO\". Note\ that SCRAM-SHA-1 is
|
||||
required for authenticating to MongoDB 3.0 and later.")
|
||||
|
||||
set (ENABLE_SASL AUTO CACHE STRING
|
||||
"Enable SASL authentication (Kerberos). Options are \"CYRUS\" to use Cyrus
|
||||
SASL, \"SSPI\" to use Windows Native SSPI, \"GSSAPI\" to use macOS Native GSS,
|
||||
\"AUTO\",\ or \"OFF\". These options are case-sensitive.")
|
||||
|
||||
set (ENABLE_STATIC AUTO CACHE STRING "Build static libmongoc. Set to ON/AUTO/OFF, default AUTO.")
|
||||
option (ENABLE_TESTS "Build MongoDB C Driver tests." ON)
|
||||
option (ENABLE_EXAMPLES "Build MongoDB C Driver examples." ON)
|
||||
set (ENABLE_SRV AUTO CACHE STRING "Support mongodb+srv URIs. Set to ON/AUTO/OFF, default AUTO.")
|
||||
option (ENABLE_MAINTAINER_FLAGS "Use strict compiler checks" OFF)
|
||||
option (ENABLE_AUTOMATIC_INIT_AND_CLEANUP "Enable automatic init and cleanup (GCC only)" ON)
|
||||
option (ENABLE_CRYPTO_SYSTEM_PROFILE "Use system crypto profile (OpenSSL only)" OFF)
|
||||
option (ENABLE_TRACING "Turn on verbose debug output" OFF)
|
||||
option (ENABLE_COVERAGE "Turn on compile options for lcov" OFF)
|
||||
set (ENABLE_SHM_COUNTERS AUTO CACHE STRING "Enable memory performance counters that use shared memory on Linux. Set to ON/AUTO/OFF, default AUTO.")
|
||||
set (ENABLE_MONGOC ON CACHE STRING "Whether to build libmongoc. Set to ON/OFF, default ON.")
|
||||
set (ENABLE_BSON AUTO CACHE STRING "Whether to build libbson. Set to ON/AUTO/SYSTEM, default AUTO.")
|
||||
set (ENABLE_SNAPPY AUTO CACHE STRING "Enable snappy support. Set to ON/AUTO/OFF, default AUTO.")
|
||||
set (ENABLE_ZLIB AUTO CACHE STRING "Enable zlib support")
|
||||
option (ENABLE_MAN_PAGES "Build MongoDB C Driver manual pages." OFF)
|
||||
option (ENABLE_HTML_DOCS "Build MongoDB C Driver HTML documentation." OFF)
|
||||
option (ENABLE_EXTRA_ALIGNMENT
|
||||
"Turn on extra alignment of libbson types. Set to ON/OFF, default ON.\
|
||||
Required for the 1.0 ABI but better disabled."
|
||||
ON
|
||||
)
|
||||
option (ENABLE_RDTSCP
|
||||
"Fast performance counters on Intel using the RDTSCP instruction"
|
||||
OFF
|
||||
)
|
||||
option (ENABLE_APPLE_FRAMEWORK "Build libraries as frameworks on darwin platforms" OFF)
|
||||
set (ENABLE_ICU AUTO CACHE STRING "Enable ICU support, necessary to use non-ASCII usernames or passwords, default AUTO.")
|
||||
option (ENABLE_UNINSTALL "Enable creation of uninstall script and associate uninstall build target." ON)
|
||||
|
||||
project (mongo-c-driver C)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set (CMAKE_BUILD_TYPE "RelWithDebInfo")
|
||||
message (
|
||||
STATUS "No CMAKE_BUILD_TYPE selected, defaulting to ${CMAKE_BUILD_TYPE}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
set (CMAKE_MODULE_PATH
|
||||
${CMAKE_MODULE_PATH}
|
||||
${PROJECT_SOURCE_DIR}/build/cmake
|
||||
${PROJECT_SOURCE_DIR}/build/cmake/make_dist
|
||||
)
|
||||
|
||||
include (InstallRequiredSystemLibraries)
|
||||
include (GNUInstallDirs)
|
||||
|
||||
# Set MONGOC_MAJOR_VERSION, MONGOC_MINOR_VERSION, etc.
|
||||
include (LoadVersion)
|
||||
LoadVersion (${PROJECT_SOURCE_DIR}/VERSION_CURRENT MONGOC)
|
||||
LoadVersion (${PROJECT_SOURCE_DIR}/VERSION_RELEASED MONGOC_RELEASED)
|
||||
|
||||
include (MaintainerFlags)
|
||||
|
||||
if ( (ENABLE_BUILD_DEPENDECIES STREQUAL OFF) AND (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) )
|
||||
set (ENABLE_BUILD_DEPENDECIES ON)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_EXTRA_ALIGNMENT STREQUAL ON)
|
||||
set (BSON_EXTRA_ALIGN 1)
|
||||
else ()
|
||||
set (BSON_EXTRA_ALIGN 0)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_RDTSCP)
|
||||
set (MONGOC_ENABLE_RDTSCP 1)
|
||||
else ()
|
||||
set (MONGOC_ENABLE_RDTSCP 0)
|
||||
endif ()
|
||||
|
||||
if (NOT ENABLE_MONGOC MATCHES "ON|OFF")
|
||||
message (FATAL_ERROR "ENABLE_MONGOC option must be ON or OFF")
|
||||
endif ()
|
||||
|
||||
if (NOT ENABLE_BSON MATCHES "ON|AUTO|SYSTEM")
|
||||
message (FATAL_ERROR "ENABLE_BSON option must be ON, AUTO, or SYSTEM")
|
||||
endif ()
|
||||
|
||||
if (ENABLE_BSON STREQUAL SYSTEM)
|
||||
# The input variable BSON_ROOT_DIR is respected for backwards compatibility,
|
||||
# but you should use the standard CMAKE_PREFIX_PATH instead.
|
||||
message (STATUS "Searching for libbson CMake packages")
|
||||
find_package (libbson-1.0
|
||||
"${MONGOC_MAJOR_VERSION}.${MONGOC_MINOR_VERSION}.${MONGOC_MICRO_VERSION}"
|
||||
HINTS
|
||||
${BSON_ROOT_DIR})
|
||||
|
||||
if (ENABLE_BSON STREQUAL SYSTEM AND NOT BSON_LIBRARIES)
|
||||
message (FATAL_ERROR "System libbson not found")
|
||||
endif ()
|
||||
|
||||
if (BSON_LIBRARIES)
|
||||
message ("-- libbson found version \"${BSON_VERSION}\"")
|
||||
message ("-- libbson include path \"${BSON_INCLUDE_DIRS}\"")
|
||||
message ("-- libbson libraries \"${BSON_LIBRARIES}\"")
|
||||
message ("-- disabling test-libmongoc since using system libbson")
|
||||
SET (ENABLE_TESTS OFF)
|
||||
|
||||
if (ENABLE_STATIC MATCHES "ON|AUTO")
|
||||
find_package (libbson-static-1.0
|
||||
"${MONGOC_MAJOR_VERSION}.${MONGOC_MINOR_VERSION}.${MONGOC_MICRO_VERSION}"
|
||||
HINTS
|
||||
${BSON_ROOT_DIR})
|
||||
|
||||
if (ENABLE_STATIC STREQUAL ON AND NOT BSON_STATIC_LIBRARY)
|
||||
message (FATAL_ERROR "Static libbson not found. Pass -DENABLE_STATIC=OFF")
|
||||
endif ()
|
||||
|
||||
if (BSON_STATIC_LIBRARY)
|
||||
set (MONGOC_ENABLE_STATIC ON)
|
||||
endif ()
|
||||
|
||||
message ("-- libbson-static found version \"${BSON_STATIC_VERSION}\"")
|
||||
message ("-- libbson-static include path \"${BSON_STATIC_INCLUDE_DIRS}\"")
|
||||
message ("-- libbson-static libraries \"${BSON_STATIC_LIBRARIES}\"")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
unset (dist_generated CACHE)
|
||||
unset (dist_generated_depends CACHE)
|
||||
|
||||
set (BUILD_SOURCE_DIR ${CMAKE_BINARY_DIR})
|
||||
|
||||
include (MakeDistFiles)
|
||||
|
||||
# Ensure the default behavior: don't ignore RPATH settings.
|
||||
set (CMAKE_SKIP_BUILD_RPATH OFF)
|
||||
|
||||
# Ensure the default behavior: don't use the final install destination as the
|
||||
# temporary RPATH for executables (ensure we can run tests and programs from
|
||||
# the build directory).
|
||||
set (CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
|
||||
|
||||
# Include any custom library paths in the final RPATH.
|
||||
set (CMAKE_INSTALL_RPATH_USE_LINK_PATH ON)
|
||||
|
||||
# Install libs with names like @rpath/libmongoc-1.0.0.dylib, not bare names.
|
||||
set (CMAKE_MACOSX_RPATH ON)
|
||||
|
||||
# https://cmake.org/cmake/help/v3.11/policy/CMP0042.html
|
||||
# Enable a CMake 3.0+ policy that sets CMAKE_MACOSX_RPATH by default, and
|
||||
# silence a CMake 3.11 warning that the old behavior is deprecated.
|
||||
cmake_policy (SET CMP0042 NEW)
|
||||
|
||||
if (NOT BSON_LIBRARIES)
|
||||
message (" -- Using bundled libbson")
|
||||
if (ENABLE_STATIC MATCHES "ON|AUTO")
|
||||
set (MONGOC_ENABLE_STATIC ON)
|
||||
endif ()
|
||||
add_subdirectory (src/libbson)
|
||||
# Defined in src/libbson/CMakeLists.txt
|
||||
set (BSON_STATIC_LIBRARIES bson_static)
|
||||
set (BSON_LIBRARIES bson_shared)
|
||||
set (BSON_STATIC_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/src/libbson/src" "${PROJECT_BINARY_DIR}/src/libbson/src")
|
||||
set (BSON_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/src/libbson/src" "${PROJECT_BINARY_DIR}/src/libbson/src")
|
||||
set (BSON_STATIC_DEFINITIONS "BSON_STATIC")
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
add_definitions (-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif ()
|
||||
|
||||
add_definitions (-D_GNU_SOURCE)
|
||||
add_definitions (-D_BSD_SOURCE)
|
||||
add_definitions (-D_DEFAULT_SOURCE)
|
||||
|
||||
if (ENABLE_MONGOC)
|
||||
|
||||
if (ENABLE_TESTS AND NOT MONGOC_ENABLE_STATIC)
|
||||
message (FATAL_ERROR "ENABLE_TESTS requires ENABLE_STATIC")
|
||||
endif ()
|
||||
|
||||
if (NOT ENABLE_SSL MATCHES "DARWIN|WINDOWS|OPENSSL|LIBRESSL|AUTO|OFF")
|
||||
message (FATAL_ERROR
|
||||
"ENABLE_SSL option must be DARWIN, WINDOWS, OPENSSL, LIBRESSL, AUTO, or OFF")
|
||||
endif ()
|
||||
|
||||
set (SOURCE_DIR "${PROJECT_SOURCE_DIR}/")
|
||||
|
||||
set (ZLIB_SOURCES
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/adler32.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/crc32.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/deflate.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/infback.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/inffast.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/inflate.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/inftrees.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/trees.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/zutil.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/compress.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/uncompr.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/gzclose.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/gzlib.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/gzread.c
|
||||
${SOURCE_DIR}/src/zlib-1.2.11/gzwrite.c
|
||||
)
|
||||
|
||||
set (MONGOC_ENABLE_ICU 0)
|
||||
|
||||
set (CPACK_RESOURCE_FILE_LICENSE "${SOURCE_DIR}/COPYING")
|
||||
|
||||
include (CPack)
|
||||
|
||||
# Ensure the default behavior: don't ignore RPATH settings.
|
||||
set (CMAKE_SKIP_BUILD_RPATH OFF)
|
||||
|
||||
if (APPLE)
|
||||
# Until CDRIVER-520.
|
||||
add_definitions (-Wno-deprecated-declarations)
|
||||
endif ()
|
||||
|
||||
add_subdirectory (src/libmongoc)
|
||||
|
||||
if (ENABLE_MAN_PAGES STREQUAL ON OR ENABLE_HTML_DOCS STREQUAL ON)
|
||||
find_package (Sphinx REQUIRED)
|
||||
add_custom_target (doc
|
||||
ALL
|
||||
DEPENDS
|
||||
$<$<STREQUAL:"${ENABLE_BSON}","ON">:bson-doc>
|
||||
$<$<STREQUAL:"${ENABLE_MONGOC}","ON">:mongoc-doc>
|
||||
)
|
||||
endif ()
|
||||
|
||||
# Implement 'dist' and 'distcheck' targets
|
||||
#
|
||||
# CMake does not implement anything like 'dist' and 'distcheck' from autotools.
|
||||
# This implementation is based on the one in GnuCash.
|
||||
|
||||
add_subdirectory (build)
|
||||
# sub-directory 'doc' was already included above
|
||||
add_subdirectory (orchestration_configs)
|
||||
add_subdirectory (src)
|
||||
# 'src/libbson' was already included, so 'src' will not include it directly
|
||||
# 'src/libmongoc' was already included, so 'src' will not include it directly
|
||||
|
||||
set (PACKAGE_PREFIX "mongo-c-driver-${MONGOC_VERSION}")
|
||||
set (DIST_FILE "${PACKAGE_PREFIX}.tar.gz")
|
||||
|
||||
set (top_DIST_local
|
||||
CMakeLists.txt
|
||||
CONTRIBUTING.md
|
||||
COPYING
|
||||
NEWS
|
||||
README.rst
|
||||
THIRD_PARTY_NOTICES
|
||||
VERSION_CURRENT
|
||||
VERSION_RELEASED
|
||||
# This sub-directory is added later, so manually include here
|
||||
generate_uninstall/CMakeLists.txt
|
||||
)
|
||||
|
||||
set_local_dist (top_DIST ${top_DIST_local})
|
||||
|
||||
set (ALL_DIST
|
||||
${top_DIST}
|
||||
${build_DIST}
|
||||
${orchestration_configs_DIST}
|
||||
${src_DIST}
|
||||
${src_libbson_DIST}
|
||||
${src_libmongoc_DIST}
|
||||
)
|
||||
|
||||
# Write a dist manifest
|
||||
string (REPLACE ";" "\n" ALL_DIST_LINES "${ALL_DIST}")
|
||||
file (WRITE ${CMAKE_BINARY_DIR}/dist_manifest.txt ${ALL_DIST_LINES})
|
||||
|
||||
# This is the command that produces the distribution tarball
|
||||
add_custom_command (OUTPUT ${DIST_FILE}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D CMAKE_MODULE_PATH=${PROJECT_SOURCE_DIR}/build/cmake/make_dist
|
||||
-D PACKAGE_PREFIX=${PACKAGE_PREFIX}
|
||||
-D MONGOC_SOURCE_DIR=${CMAKE_SOURCE_DIR}
|
||||
-D BUILD_SOURCE_DIR=${BUILD_SOURCE_DIR}
|
||||
-D SHELL=${SHELL}
|
||||
"-Ddist_generated=\"${dist_generated}\""
|
||||
-P ${PROJECT_SOURCE_DIR}/build/cmake/make_dist/MakeDist.cmake
|
||||
|
||||
DEPENDS
|
||||
${ALL_DIST} ${dist_generated_depends}
|
||||
)
|
||||
|
||||
if (ENABLE_BSON MATCHES "ON|AUTO" AND ENABLE_MAN_PAGES STREQUAL ON AND ENABLE_HTML_DOCS STREQUAL ON)
|
||||
# Since our 'dist' implementation does not add top-level targets for every
|
||||
# file to be included, we declare a dependency on the 'mongo-doc' target so
|
||||
# that documentation is built before the distribution tarball is generated.
|
||||
add_custom_target (dist DEPENDS doc ${DIST_FILE})
|
||||
|
||||
add_custom_target (distcheck DEPENDS dist
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D CMAKE_MODULE_PATH=${PROJECT_SOURCE_DIR}/build/cmake/make_dist
|
||||
-D CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}
|
||||
-D PACKAGE_PREFIX=${PACKAGE_PREFIX}
|
||||
-D CMAKE_C_FLAGS=${CMAKE_C_FLAGS}
|
||||
-D CMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
|
||||
-P ${PROJECT_SOURCE_DIR}/build/cmake/make_dist/MakeDistCheck.cmake
|
||||
)
|
||||
else ()
|
||||
string (CONCAT DISTERRMSG
|
||||
"The dist and distcheck targets disabled. Set ENABLE_BSON=ON, "
|
||||
"ENABLE_MAN_PAGES=ON, and ENABLE_HTML_DOCS=ON to enable."
|
||||
)
|
||||
|
||||
add_custom_target (dist
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${DISTERRMSG}"
|
||||
)
|
||||
|
||||
add_custom_target (distcheck
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "${DISTERRMSG}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
endif ()
|
||||
|
||||
if (ENABLE_UNINSTALL)
|
||||
if (WIN32)
|
||||
if (ENABLE_MONGOC)
|
||||
set (UNINSTALL_PROG "uninstall.cmd")
|
||||
else ()
|
||||
set (UNINSTALL_PROG "uninstall-bson.cmd")
|
||||
endif ()
|
||||
else ()
|
||||
if (ENABLE_MONGOC)
|
||||
set (UNINSTALL_PROG "uninstall.sh")
|
||||
else ()
|
||||
set (UNINSTALL_PROG "uninstall-bson.sh")
|
||||
endif ()
|
||||
endif ()
|
||||
set (UNINSTALL_PROG_DIR "${CMAKE_INSTALL_DATADIR}/mongo-c-driver")
|
||||
|
||||
# Create uninstall program and associated uninstall target
|
||||
#
|
||||
# This needs to be last (after all other add_subdirectory calls) to ensure that
|
||||
# the generated uninstall program is complete and correct
|
||||
add_subdirectory (generate_uninstall)
|
||||
endif ()
|
258
contrib/mongoc/mongo-c-driver-1.13.1/CONTRIBUTING.md
Normal file
258
contrib/mongoc/mongo-c-driver-1.13.1/CONTRIBUTING.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# Contributing to mongo-c-driver
|
||||
|
||||
Thanks for considering contributing to the mongo-c-driver!
|
||||
|
||||
This document intends to be a short guide to helping you contribute to the codebase.
|
||||
It expects a familiarity with the C programming language and writing portable software.
|
||||
Whenever in doubt, feel free to ask others that have contributed or look at the existing body of code.
|
||||
|
||||
|
||||
## Guidelines
|
||||
|
||||
The mongo-c-driver has a few guidelines that help direct the process.
|
||||
|
||||
|
||||
### Portability
|
||||
|
||||
mongo-c-driver is portable software. It needs to run on a multitude of
|
||||
operating systems and architectures.
|
||||
|
||||
* Linux (RHEL 5 and newer)
|
||||
* FreeBSD (10 and newer)
|
||||
* Windows (Vista and newer)
|
||||
* macOS (10.8 and newer)
|
||||
* ARM/SPARC/x86/x86_64
|
||||
|
||||
|
||||
### Licensing
|
||||
|
||||
Some of the mongo-c-driver users embed the library statically in their
|
||||
products. Therefore, the driver and all contributions must be liberally
|
||||
licensed. As a policy, we have chosen Apache 2.0 as the license for the
|
||||
project.
|
||||
|
||||
|
||||
### Coding Style
|
||||
|
||||
We try not to be pedantic with taking contributions that are not properly
|
||||
formatted, but we will likely perform a followup commit that cleans things up.
|
||||
The basics are, in vim:
|
||||
|
||||
```
|
||||
: set ts=3 sw=3 et
|
||||
```
|
||||
|
||||
3 space tabs, insert spaces instead of tabs.
|
||||
|
||||
For all the gory details, see [.clang-format](.clang-format)
|
||||
|
||||
### Adding a new error code or domain
|
||||
|
||||
When adding a new error code or domain, you must do the following. This is most
|
||||
applicable if you are adding a new symbol with a bson_error_t as a parameter,
|
||||
and the existing codes or domains are inappropriate.
|
||||
|
||||
- Add the domain to `mongoc_error_domain_t` in `src/mongoc/mongoc-error.h`
|
||||
- Add the code to `mongoc_error_code_t` in `src/mongoc/mongoc-error.h`
|
||||
- Add documentation for the domain or code to the table in `doc/mongoc_errors.rst`
|
||||
|
||||
### Adding a new symbol
|
||||
|
||||
This should be done rarely but there are several things that you need to do
|
||||
when adding a new symbol.
|
||||
|
||||
- Add documentation for the new symbol in `doc/mongoc_your_new_symbol_name.rst`
|
||||
|
||||
### Documentation
|
||||
|
||||
We strive to document all symbols. See doc/ for documentation examples. If you
|
||||
add a new public function, add a new .rst file describing the function so that
|
||||
we can generate man pages and HTML for it.
|
||||
|
||||
For complex internal functions, comment above the function definition with
|
||||
a block comment like the following:
|
||||
|
||||
```
|
||||
/*--------------------------------------------------------------------------
|
||||
*
|
||||
* mongoc_cmd_parts_append_read_write --
|
||||
*
|
||||
* Append user-supplied options to @parts->command_extra, taking the
|
||||
* selected server's max wire version into account.
|
||||
*
|
||||
* Return:
|
||||
* True if the options were successfully applied. If any options are
|
||||
* invalid, returns false and fills out @error. In that case @parts is
|
||||
* invalid and must not be used.
|
||||
*
|
||||
* Side effects:
|
||||
* May partly apply options before returning an error.
|
||||
*
|
||||
*--------------------------------------------------------------------------
|
||||
*/
|
||||
```
|
||||
|
||||
Public functions do not need these comment blocks, since they are documented in
|
||||
the .rst files.
|
||||
|
||||
|
||||
### Testing
|
||||
|
||||
To run the entire test suite, including authentication tests,
|
||||
start `mongod` with auth enabled:
|
||||
|
||||
```
|
||||
$ mongod --auth
|
||||
```
|
||||
|
||||
In another terminal, use the `mongo` shell to create a user:
|
||||
|
||||
```
|
||||
$ mongo --eval "db.createUser({user: 'admin', pwd: 'pass', roles: ['root']})" admin
|
||||
```
|
||||
|
||||
Authentication in MongoDB 3.0 and later uses SCRAM-SHA-1, which in turn
|
||||
requires a driver built with SSL.
|
||||
|
||||
Set the user and password environment variables, then build and run the tests:
|
||||
|
||||
```
|
||||
$ export MONGOC_TEST_USER=admin
|
||||
$ export MONGOC_TEST_PASSWORD=pass
|
||||
$ ./test-libmongoc
|
||||
```
|
||||
|
||||
Additional environment variables:
|
||||
|
||||
* `MONGOC_TEST_HOST`: default `localhost`, the host running MongoDB.
|
||||
* `MONGOC_TEST_PORT`: default 27017, MongoDB's listening port.
|
||||
* `MONGOC_TEST_URI`: override both host and port with a full connection string,
|
||||
like "mongodb://server1,server2".
|
||||
* `MONGOC_TEST_SERVER_LOG`: set to `stdout` or `stderr` for wire protocol
|
||||
logging from tests that use `mock_server_t`. Set to `json` to include these
|
||||
logs in the test framework's JSON output, in a format compatible with
|
||||
[Evergreen](https://github.com/evergreen-ci/evergreen).
|
||||
* `MONGOC_TEST_MONITORING_VERBOSE`: set to `on` for verbose output from
|
||||
Application Performance Monitoring tests.
|
||||
* `MONGOC_TEST_COMPRESSORS=snappy,zlib`: wire protocol compressors to use
|
||||
|
||||
If you start `mongod` with SSL, set these variables to configure how
|
||||
`test-libmongoc` connects to it:
|
||||
|
||||
* `MONGOC_TEST_SSL`: set to `on` to connect to the server with SSL.
|
||||
* `MONGOC_TEST_SSL_PEM_FILE`: path to a client PEM file.
|
||||
* `MONGOC_TEST_SSL_PEM_PWD`: the PEM file's password.
|
||||
* `MONGOC_TEST_SSL_CA_FILE`: path to a certificate authority file.
|
||||
* `MONGOC_TEST_SSL_CA_DIR`: path to a certificate authority directory.
|
||||
* `MONGOC_TEST_SSL_CRL_FILE`: path to a certificate revocation list.
|
||||
* `MONGOC_TEST_SSL_WEAK_CERT_VALIDATION`: set to `on` to relax the client's
|
||||
validation of the server's certificate.
|
||||
|
||||
The SASL / GSSAPI / Kerberos tests are skipped by default. To run them, set up a
|
||||
separate `mongod` with Kerberos and set its host and Kerberos principal name
|
||||
as environment variables:
|
||||
|
||||
* `MONGOC_TEST_GSSAPI_HOST`
|
||||
* `MONGOC_TEST_GSSAPI_USER`
|
||||
|
||||
URI-escape the username, for example write "user@realm" as "user%40realm".
|
||||
The user must be authorized to query `kerberos.test`.
|
||||
|
||||
MongoDB 3.2 adds support for readConcern, but does not enable support for
|
||||
read concern majority by default. mongod must be launched using
|
||||
`--enableMajorityReadConcern`.
|
||||
The test framework does not (and can't) automatically discover if this option was
|
||||
provided to MongoDB, so an additional variable must be set to enable these tests:
|
||||
|
||||
* `MONGOC_ENABLE_MAJORITY_READ_CONCERN`
|
||||
|
||||
Set this environment variable to `on` if MongoDB has enabled majority read concern.
|
||||
|
||||
Some tests require Internet access, e.g. to check the error message when failing
|
||||
to open a MongoDB connection to example.com. Skip them with:
|
||||
|
||||
* `MONGOC_TEST_OFFLINE=on`
|
||||
|
||||
Some tests require a running MongoDB server. Skip them with:
|
||||
|
||||
* `MONGOC_TEST_SKIP_LIVE=on`
|
||||
|
||||
For quick checks during development, disable long-running tests:
|
||||
|
||||
* `MONGOC_TEST_SKIP_SLOW=on`
|
||||
|
||||
Some tests run against a local mock server, these can be skipped with:
|
||||
|
||||
* `MONGOC_TEST_SKIP_MOCK=on`
|
||||
|
||||
If you have started with MongoDB with `--ipv6`, you can test IPv6 with:
|
||||
|
||||
* `MONGOC_CHECK_IPV6=on`
|
||||
|
||||
The tests for mongodb+srv:// connection strings require some setup, see the
|
||||
Initial DNS Seedlist Discovery Spec. By default these connection strings are
|
||||
NOT tested, enable them with:
|
||||
|
||||
* `MONGOC_TEST_DNS=on`
|
||||
|
||||
The mock server timeout threshold for future functions can be set with:
|
||||
|
||||
* `MONGOC_TEST_FUTURE_TIMEOUT_MS=<int>`
|
||||
|
||||
This is useful for debugging, so future calls don't timeout when stepping through code.
|
||||
|
||||
All tests should pass before submitting a patch.
|
||||
|
||||
## Configuring the test runner
|
||||
|
||||
The test runner can be configured with command-line options. Run `test-libmongoc
|
||||
--help` for details.
|
||||
|
||||
To run just a specific portion of the test suite use the -l option like so:
|
||||
|
||||
```
|
||||
$ ./test-libmongoc -l "/server_selection/*"
|
||||
```
|
||||
|
||||
The full list of tests is shown in the help.
|
||||
|
||||
## Creating and checking a distribution tarball
|
||||
|
||||
The `make distcheck` command can be used to confirm that any modifications are
|
||||
able to be packaged into the distribution tarball and that the resulting
|
||||
distribution tarball can be used to successfully build the project.
|
||||
|
||||
A failure of the `make distcheck` target is an indicator of an oversight in the
|
||||
modification to the project. For example, if a new source file is added to the
|
||||
project but it is not added to the proper distribution list, it is possible that
|
||||
the distribution tarball will be created without that file. An attempt to build
|
||||
the project without the file is likely to fail.
|
||||
|
||||
When `make distcheck` is invoked, several things happen. The `dist` target is
|
||||
executed to create a distribution tarball. Then the tarball is unpacked,
|
||||
configured (with an invocation of `cmake`), built (by calling `make`), installed
|
||||
(by calling `make install`), and tested (by calling `make check`). Three
|
||||
environment variables can be used to modify these steps.
|
||||
|
||||
To adjust the options passed to `make` during the build step, set:
|
||||
|
||||
* `DISTCHECK_BUILD_OPTS`
|
||||
|
||||
If this variable is not set, then `make` is called with a default of "-j 8".
|
||||
|
||||
To adjust the options passed to `make install` during the installation step,
|
||||
set:
|
||||
|
||||
* `DISTCHECK_INSTALL_OPTS`
|
||||
|
||||
To adjust the options passed to `make check` during the test step, set:
|
||||
|
||||
* `DISTCHECK_CHECK_OPTS`
|
||||
|
||||
Remember, if you want to modify the top-level `make` invocation, you will need
|
||||
to pass options on the command line as normal.
|
||||
|
||||
For example, the command `make -j 6 distcheck DISTCHECK_BUILD_OPTS="-j 4"` will
|
||||
call the standard sequence of targets depended upon by `distcheck` with a
|
||||
parallelism level of 6, while the build step that is later called by the
|
||||
`distcheck` target will be executed with a parallelism level of 4.
|
177
contrib/mongoc/mongo-c-driver-1.13.1/COPYING
Normal file
177
contrib/mongoc/mongo-c-driver-1.13.1/COPYING
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
2413
contrib/mongoc/mongo-c-driver-1.13.1/NEWS
Normal file
2413
contrib/mongoc/mongo-c-driver-1.13.1/NEWS
Normal file
File diff suppressed because it is too large
Load Diff
90
contrib/mongoc/mongo-c-driver-1.13.1/README.rst
Normal file
90
contrib/mongoc/mongo-c-driver-1.13.1/README.rst
Normal file
@@ -0,0 +1,90 @@
|
||||
==============
|
||||
mongo-c-driver
|
||||
==============
|
||||
|
||||
About
|
||||
=====
|
||||
|
||||
mongo-c-driver is a project that includes two libraries:
|
||||
|
||||
- libmongoc, a client library written in C for MongoDB.
|
||||
- libbson, a library providing useful routines related to building, parsing, and iterating BSON documents.
|
||||
|
||||
If libmongoc is not needed, it is possible to build and install only libbson.
|
||||
|
||||
Documentation / Support / Feedback
|
||||
==================================
|
||||
|
||||
The documentation is available at http://mongoc.org/.
|
||||
For issues with, questions about, or feedback for libmongoc, please look into
|
||||
our `support channels <http://www.mongodb.org/about/support>`_. Please
|
||||
do not email any of the libmongoc developers directly with issues or
|
||||
questions - you're more likely to get an answer on the `mongodb-user list`_
|
||||
on Google Groups.
|
||||
|
||||
Bugs / Feature Requests
|
||||
=======================
|
||||
|
||||
Think you’ve found a bug? Want to see a new feature in libmongoc? Please open a
|
||||
case in our issue management tool, JIRA:
|
||||
|
||||
- `Create an account and login <https://jira.mongodb.org>`_.
|
||||
- Navigate to `the CDRIVER project <https://jira.mongodb.org/browse/CDRIVER>`_.
|
||||
- Click **Create Issue** - Please provide as much information as possible about the issue type and how to reproduce it.
|
||||
|
||||
Bug reports in JIRA for all driver projects (i.e. CDRIVER, CSHARP, JAVA) and the
|
||||
Core Server (i.e. SERVER) project are **public**.
|
||||
|
||||
How To Ask For Help
|
||||
-------------------
|
||||
|
||||
If you are having difficulty building the driver after reading the below instructions, please email
|
||||
the `mongodb-user list`_ to ask for help. Please include in your email all of the following
|
||||
information:
|
||||
|
||||
- The version of the driver you are trying to build (branch or tag).
|
||||
- Examples: master branch, 1.9.5 tag
|
||||
- Host OS, version, and architecture.
|
||||
- Examples: Windows 10 64-bit x86, Ubuntu 16.04 64-bit x86, macOS 10.13
|
||||
- C Compiler and version.
|
||||
- Examples: GCC 7.3.0, Visual Studio Community 2017, clang 3.9, XCode 9.3
|
||||
- The output of ``cmake``.
|
||||
- The text of the error you encountered.
|
||||
|
||||
Failure to include the relevant information will delay a useful response.
|
||||
Here is a made-up example of a help request that provides the relevant
|
||||
information:
|
||||
|
||||
Hello, I'm trying to build the C driver with Kerberos support, from
|
||||
mongo-c-driver-1.9.5.tar.gz. I'm on Ubuntu 16.04, 64-bit Intel, with gcc
|
||||
5.4.0. I run CMake like::
|
||||
|
||||
$ cmake .
|
||||
-- The C compiler identification is ;GNU 5.4.0
|
||||
-- Check for working C compiler: /usr/bin/cc
|
||||
-- Check for working C compiler: /usr/bin/cc -- works
|
||||
|
||||
... SNIPPED OUTPUT, but when you ask for help, include full output without any omissions ...
|
||||
|
||||
-- Searching for libsasl2
|
||||
-- Not found (specify -DCMAKE_LIBRARY_PATH=/path/to/sasl/lib for SASL support)
|
||||
CMake Error at CMakeLists.txt:10 (_message):
|
||||
SASL not found
|
||||
|
||||
Can you tell me what I need to install? Thanks!
|
||||
|
||||
.. _mongodb-user list: http://groups.google.com/group/mongodb-user
|
||||
|
||||
Security Vulnerabilities
|
||||
------------------------
|
||||
|
||||
If you’ve identified a security vulnerability in a driver or any other
|
||||
MongoDB project, please report it according to the `instructions here
|
||||
<http://docs.mongodb.org/manual/tutorial/create-a-vulnerability-report>`_.
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
Detailed installation instructions are in the manual:
|
||||
http://mongoc.org/libmongoc/current/installing.html
|
157
contrib/mongoc/mongo-c-driver-1.13.1/THIRD_PARTY_NOTICES
Normal file
157
contrib/mongoc/mongo-c-driver-1.13.1/THIRD_PARTY_NOTICES
Normal file
@@ -0,0 +1,157 @@
|
||||
The MongoDB C Driver uses third-party code distributed under different licenses.
|
||||
|
||||
License notice for common-b64.c
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
ISC License
|
||||
|
||||
Copyright: 1996, 1998 Internet Software Consortium
|
||||
1995 International Business Machines, Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
|
||||
International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
permission under its copyrights to use, copy, modify, and distribute this
|
||||
Software with or without fee, provided that the above copyright notice and
|
||||
all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
not be used in connection with the marketing of any product incorporating
|
||||
the Software or modifications thereof, without specific, written prior
|
||||
permission.
|
||||
|
||||
To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
under its patents, if any, for the use, sale or manufacture of products to
|
||||
the extent that such products are used for performing Domain Name System
|
||||
dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
granted for any product per se or for any other function of any product.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
|
||||
License notice for taglist.py
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Portions Copyright 2007-2009 by the Sphinx team.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
License notice for mongoc.css_t
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Portions Copyright 2013 by Ignacy Sokolowski.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
License notice for zlib
|
||||
-------------------------------------------------------------------------------
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.2.11, January 15th, 2017
|
||||
|
||||
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
The data format used by the zlib library is described by RFCs (Request for
|
||||
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
|
||||
*/
|
||||
|
||||
License notice for common-md5.c
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
ZLib License
|
||||
|
||||
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
ghost@aladdin.com
|
1
contrib/mongoc/mongo-c-driver-1.13.1/VERSION_CURRENT
Normal file
1
contrib/mongoc/mongo-c-driver-1.13.1/VERSION_CURRENT
Normal file
@@ -0,0 +1 @@
|
||||
1.13.1
|
1
contrib/mongoc/mongo-c-driver-1.13.1/VERSION_RELEASED
Normal file
1
contrib/mongoc/mongo-c-driver-1.13.1/VERSION_RELEASED
Normal file
@@ -0,0 +1 @@
|
||||
1.13.1
|
@@ -0,0 +1,56 @@
|
||||
# Fabricate our own copy of the install manifest, since the installation has not
|
||||
# generated the final version yet at this point
|
||||
|
||||
set (UNINSTALL_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
|
||||
if (WIN32)
|
||||
string (REPLACE "/" "\\\\" CMAKE_INSTALL_PREFIX_WIN32
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
)
|
||||
install (CODE "
|
||||
string(REPLACE \";\" \"\\n\" MONGOC_INSTALL_MANIFEST_CONTENT
|
||||
\"\${CMAKE_INSTALL_MANIFEST_FILES}\")
|
||||
string(REPLACE \"/\" \"\\\\\" MONGOC_INSTALL_MANIFEST_CONTENT_WIN32
|
||||
\"\${MONGOC_INSTALL_MANIFEST_CONTENT}\")
|
||||
file(WRITE \"mongoc_install_manifest.txt\"
|
||||
\"\${MONGOC_INSTALL_MANIFEST_CONTENT_WIN32}\")
|
||||
execute_process (
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E env
|
||||
ENABLE_MONGOC=${ENABLE_MONGOC}
|
||||
cmd.exe /c
|
||||
\"${PROJECT_SOURCE_DIR}/build/generate-uninstall.cmd\"
|
||||
mongoc_install_manifest.txt
|
||||
${CMAKE_INSTALL_PREFIX_WIN32}
|
||||
OUTPUT_FILE
|
||||
\"${CMAKE_CURRENT_BINARY_DIR}/${UNINSTALL_PROG}\"
|
||||
)
|
||||
")
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/${UNINSTALL_PROG}" DESTINATION "${UNINSTALL_PROG_DIR}" PERMISSIONS ${UNINSTALL_PERMISSIONS})
|
||||
|
||||
add_custom_target (uninstall
|
||||
COMMAND call "${CMAKE_CURRENT_BINARY_DIR}/${UNINSTALL_PROG}"
|
||||
)
|
||||
else ()
|
||||
install (CODE "
|
||||
string(REPLACE \";\" \"\\n\" MONGOC_INSTALL_MANIFEST_CONTENT
|
||||
\"\${CMAKE_INSTALL_MANIFEST_FILES}\")
|
||||
file(WRITE \"mongoc_install_manifest.txt\"
|
||||
\"\${MONGOC_INSTALL_MANIFEST_CONTENT}\")
|
||||
execute_process (
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E env
|
||||
ENABLE_MONGOC=${ENABLE_MONGOC}
|
||||
\"${PROJECT_SOURCE_DIR}/build/generate-uninstall.sh\"
|
||||
mongoc_install_manifest.txt
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
OUTPUT_FILE
|
||||
\"${CMAKE_CURRENT_BINARY_DIR}/${UNINSTALL_PROG}\"
|
||||
)
|
||||
")
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/${UNINSTALL_PROG}" DESTINATION "${UNINSTALL_PROG_DIR}" PERMISSIONS ${UNINSTALL_PERMISSIONS})
|
||||
|
||||
add_custom_target (uninstall
|
||||
COMMAND sh "${CMAKE_CURRENT_BINARY_DIR}/${UNINSTALL_PROG}"
|
||||
)
|
||||
endif ()
|
@@ -0,0 +1,9 @@
|
||||
file (GLOB_RECURSE orchestration_configs_DIST_pems RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.pem)
|
||||
file (GLOB_RECURSE orchestration_configs_DIST_jsons RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.json)
|
||||
|
||||
set_dist_list (orchestration_configs_DIST
|
||||
CMakeLists.txt
|
||||
${orchestration_configs_DIST_pems}
|
||||
${orchestration_configs_DIST_jsons}
|
||||
)
|
||||
|
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"auth_key": "secret",
|
||||
"id": "repl0",
|
||||
"login": "bob",
|
||||
"password": "pwd123",
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27017,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "one",
|
||||
"dc": "ny"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27018,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "two",
|
||||
"dc": "pa"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27019,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"arbiterOnly": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"sslParams": {
|
||||
"sslMode": "requireSSL",
|
||||
"sslPEMKeyFile": "/tmp/orchestration-home/server.pem",
|
||||
"sslCAFile": "/tmp/orchestration-home/ca.pem",
|
||||
"sslAllowInvalidCertificates": true,
|
||||
"sslWeakCertificateValidation" : true
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"auth_key": "secret",
|
||||
"id": "repl0",
|
||||
"login": "bob",
|
||||
"password": "pwd123",
|
||||
"authSource": "thisDB",
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27017,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "one",
|
||||
"dc": "ny"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27018,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "two",
|
||||
"dc": "pa"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27019,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"arbiterOnly": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"sslParams": {
|
||||
"sslMode": "requireSSL",
|
||||
"sslPEMKeyFile": "/tmp/orchestration-home/server.pem",
|
||||
"sslCAFile": "/tmp/orchestration-home/ca.pem",
|
||||
"sslAllowInvalidCertificates": true,
|
||||
"sslWeakCertificateValidation" : true
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"auth_key": "secret",
|
||||
"id": "repl0",
|
||||
"login": "bob",
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27017,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "one",
|
||||
"dc": "ny"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27018,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "two",
|
||||
"dc": "pa"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27019,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"arbiterOnly": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"password": "pwd123"
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"id": "repl0",
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27017,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "one",
|
||||
"dc": "ny"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27018,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "two",
|
||||
"dc": "pa"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27019,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"arbiterOnly": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"sslParams": {
|
||||
"sslMode": "requireSSL",
|
||||
"sslPEMKeyFile": "/tmp/orchestration-home/server.pem",
|
||||
"sslCAFile": "/tmp/orchestration-home/ca.pem",
|
||||
"sslAllowInvalidCertificates": true,
|
||||
"sslWeakCertificateValidation" : true
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"id": "repl0",
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27017,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "one",
|
||||
"dc": "ny"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27018,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"tags": {
|
||||
"ordinal": "two",
|
||||
"dc": "pa"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"journal": true,
|
||||
"port": 27019,
|
||||
"setParameter" : { "enableTestCommands": 1 }
|
||||
},
|
||||
"rsParams": {
|
||||
"arbiterOnly": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"id" : "standalonessl",
|
||||
"name": "mongod",
|
||||
"login": "bob",
|
||||
"password": "pwd123",
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"port": 27017
|
||||
},
|
||||
"sslParams": {
|
||||
"sslMode": "requireSSL",
|
||||
"sslPEMKeyFile": "/tmp/orchestration-home/server.pem",
|
||||
"sslCAFile": "/tmp/orchestration-home/ca.pem",
|
||||
"sslAllowInvalidCertificates": true,
|
||||
"sslWeakCertificateValidation" : true
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "standalone",
|
||||
"auth_key": "secret",
|
||||
"login": "bob",
|
||||
"name": "mongod",
|
||||
"password": "pwd123",
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"port": 27017
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "mongod",
|
||||
"procParams": {
|
||||
"ipv6": false,
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"port": 27017
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"id" : "standalonenoauthssl",
|
||||
"name": "mongod",
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"port": 27017
|
||||
},
|
||||
"sslParams": {
|
||||
"sslMode": "requireSSL",
|
||||
"sslPEMKeyFile": "/tmp/orchestration-home/server.pem",
|
||||
"sslCAFile": "/tmp/orchestration-home/ca.pem",
|
||||
"sslAllowInvalidCertificates": true,
|
||||
"sslWeakCertificateValidation" : true
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "mongod",
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"port": 27017
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "mongod",
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"storageEngine": "mmapv1",
|
||||
"port": 27017
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "mongod",
|
||||
"procParams": {
|
||||
"networkMessageCompressors": "snappy,zlib",
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"port": 27017
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "mongod",
|
||||
"procParams": {
|
||||
"networkMessageCompressors": "snappy",
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"port": 27017
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "mongod",
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"storageEngine": "wiredTiger",
|
||||
"port": 27017
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "mongod",
|
||||
"procParams": {
|
||||
"networkMessageCompressors": "zlib",
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"logappend": true,
|
||||
"journal": true,
|
||||
"port": 27017
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"id": "shard_cluster_1",
|
||||
"login": "bob",
|
||||
"password": "pwd123",
|
||||
"auth_key": "secret",
|
||||
"shards": [
|
||||
{
|
||||
"id": "sh01",
|
||||
"shardParams": {
|
||||
"members": [{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"shardsvr": true,
|
||||
"setParameter" : { "enableTestCommands": 1 },
|
||||
"port": 27217
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sh02",
|
||||
"shardParams": {
|
||||
"members": [{
|
||||
"procParams": {
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"shardsvr": true,
|
||||
"setParameter" : { "enableTestCommands": 1 },
|
||||
"port": 27218
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
],
|
||||
"routers": [
|
||||
{
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"setParameter" : { "enableTestCommands": 1 },
|
||||
"port": 27017
|
||||
},
|
||||
{
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1",
|
||||
"setParameter" : { "enableTestCommands": 1 },
|
||||
"port": 27018
|
||||
}
|
||||
],
|
||||
"sslParams": {
|
||||
"sslOnNormalPorts": true,
|
||||
"sslPEMKeyFile": "/tmp/orchestration-home/server.pem",
|
||||
"sslCAFile": "/tmp/orchestration-home/ca.pem",
|
||||
"sslWeakCertificateValidation" : true
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"id": "shard_cluster_1",
|
||||
"login": "bob",
|
||||
"password": "pwd123",
|
||||
"auth_key": "secret",
|
||||
"shards": [
|
||||
{
|
||||
"id": "sh01",
|
||||
"shardParams": {
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27217
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27218
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sh02",
|
||||
"shardParams": {
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27219
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27220
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"routers": [
|
||||
{
|
||||
"port": 27017,
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1"
|
||||
},
|
||||
{
|
||||
"port": 27018,
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1"
|
||||
}
|
||||
]
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"id": "shard_cluster_1",
|
||||
"shards": [
|
||||
{
|
||||
"id": "sh01",
|
||||
"shardParams": {
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27217
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27218
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sh02",
|
||||
"shardParams": {
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27219
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27220
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"routers": [
|
||||
{
|
||||
"port": 27017,
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1"
|
||||
},
|
||||
{
|
||||
"port": 27018,
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1"
|
||||
}
|
||||
],
|
||||
"sslParams": {
|
||||
"sslMode": "requireSSL",
|
||||
"sslPEMKeyFile": "/tmp/orchestration-home/server.pem",
|
||||
"sslCAFile": "/tmp/orchestration-home/ca.pem",
|
||||
"sslAllowInvalidCertificates": true,
|
||||
"sslWeakCertificateValidation" : true
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"id": "shard_cluster_1",
|
||||
"shards": [
|
||||
{
|
||||
"id": "sh01",
|
||||
"shardParams": {
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27217
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27218
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "sh02",
|
||||
"shardParams": {
|
||||
"members": [
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27219
|
||||
}
|
||||
},
|
||||
{
|
||||
"procParams": {
|
||||
"shardsvr": true,
|
||||
"port": 27220
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"routers": [
|
||||
{
|
||||
"port": 27017,
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1"
|
||||
},
|
||||
{
|
||||
"port": 27018,
|
||||
"ipv6": true,
|
||||
"bind_ip": "127.0.0.1,::1"
|
||||
}
|
||||
]
|
||||
}
|
38
contrib/mongoc/mongo-c-driver-1.13.1/src/CMakeLists.txt
Normal file
38
contrib/mongoc/mongo-c-driver-1.13.1/src/CMakeLists.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
# sub-directory 'libbson' was already included at the top-level
|
||||
# sub-directory 'libmongoc' was already included at the top-level
|
||||
add_subdirectory (tools)
|
||||
add_subdirectory (common)
|
||||
|
||||
# zconf.h is generated by configure_file() in the parent CMakeLists.txt
|
||||
extra_dist_generated (zlib-1.2.11/zconf.h)
|
||||
set (src_zlib_DIST
|
||||
src/zlib-1.2.11/crc32.h
|
||||
src/zlib-1.2.11/deflate.h
|
||||
src/zlib-1.2.11/gzguts.h
|
||||
src/zlib-1.2.11/inffast.h
|
||||
src/zlib-1.2.11/inffixed.h
|
||||
src/zlib-1.2.11/inflate.h
|
||||
src/zlib-1.2.11/inftrees.h
|
||||
src/zlib-1.2.11/trees.h
|
||||
src/zlib-1.2.11/zconf.h.in
|
||||
src/zlib-1.2.11/zlib.h
|
||||
src/zlib-1.2.11/zutil.h
|
||||
)
|
||||
# Strip leading directory components to make the paths relative for MakeDist.
|
||||
# The ZLIB_SOURCES list is set in the top-level CMakeLists.txt.
|
||||
foreach (zlib_src IN LISTS ZLIB_SOURCES)
|
||||
string (REPLACE "${SOURCE_DIR}/" "" zlib_src_rel ${zlib_src})
|
||||
list (APPEND src_zlib_DIST ${zlib_src_rel})
|
||||
endforeach ()
|
||||
|
||||
set_local_dist (src_DIST_local
|
||||
CMakeLists.txt
|
||||
)
|
||||
|
||||
set (src_DIST
|
||||
${src_DIST_local}
|
||||
${src_tools_DIST}
|
||||
${src_zlib_DIST}
|
||||
${src_common_DIST}
|
||||
PARENT_SCOPE
|
||||
)
|
@@ -0,0 +1,16 @@
|
||||
set (src_common_DIST_noinst_hs
|
||||
common-b64-private.h
|
||||
common-md5-private.h
|
||||
common-thread-private.h
|
||||
)
|
||||
|
||||
set (src_common_DIST_cs
|
||||
common-b64.c
|
||||
common-md5.c
|
||||
)
|
||||
|
||||
set_dist_list (src_common_DIST
|
||||
CMakeLists.txt
|
||||
${src_common_DIST_cs}
|
||||
${src_common_DIST_noinst_hs}
|
||||
)
|
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2018-present MongoDB Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_B64_PRIVATE_H
|
||||
#define COMMON_B64_PRIVATE_H
|
||||
|
||||
#if !defined(MONGOC_COMPILATION) && !defined(BSON_COMPILATION) && \
|
||||
!defined(BSON_INSIDE)
|
||||
#error "Only <mongoc/mongoc.h> or <bson/bson.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <bson/bson.h>
|
||||
|
||||
int
|
||||
bson_b64_ntop (uint8_t const *src,
|
||||
size_t srclength,
|
||||
char *target,
|
||||
size_t targsize);
|
||||
|
||||
int
|
||||
bson_b64_pton (char const *src, uint8_t *target, size_t targsize);
|
||||
|
||||
#endif /* COMMON_B64_PRIVATE_H */
|
528
contrib/mongoc/mongo-c-driver-1.13.1/src/common/common-b64.c
Normal file
528
contrib/mongoc/mongo-c-driver-1.13.1/src/common/common-b64.c
Normal file
@@ -0,0 +1,528 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include "bson/bson.h"
|
||||
#include "common-b64-private.h"
|
||||
|
||||
#define Assert(Cond) \
|
||||
if (!(Cond)) \
|
||||
abort ()
|
||||
|
||||
static const char Base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static const char Pad64 = '=';
|
||||
|
||||
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
|
||||
* The following encoding technique is taken from RFC 1521 by Borenstein
|
||||
* and Freed. It is reproduced here in a slightly edited form for
|
||||
* convenience.
|
||||
*
|
||||
* A 65-character subset of US-ASCII is used, enabling 6 bits to be
|
||||
* represented per printable character. (The extra 65th character, "=",
|
||||
* is used to signify a special processing function.)
|
||||
*
|
||||
* The encoding process represents 24-bit groups of input bits as output
|
||||
* strings of 4 encoded characters. Proceeding from left to right, a
|
||||
* 24-bit input group is formed by concatenating 3 8-bit input groups.
|
||||
* These 24 bits are then treated as 4 concatenated 6-bit groups, each
|
||||
* of which is translated into a single digit in the base64 alphabet.
|
||||
*
|
||||
* Each 6-bit group is used as an index into an array of 64 printable
|
||||
* characters. The character referenced by the index is placed in the
|
||||
* output string.
|
||||
*
|
||||
* Table 1: The Base64 Alphabet
|
||||
*
|
||||
* Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
* 0 A 17 R 34 i 51 z
|
||||
* 1 B 18 S 35 j 52 0
|
||||
* 2 C 19 T 36 k 53 1
|
||||
* 3 D 20 U 37 l 54 2
|
||||
* 4 E 21 V 38 m 55 3
|
||||
* 5 F 22 W 39 n 56 4
|
||||
* 6 G 23 X 40 o 57 5
|
||||
* 7 H 24 Y 41 p 58 6
|
||||
* 8 I 25 Z 42 q 59 7
|
||||
* 9 J 26 a 43 r 60 8
|
||||
* 10 K 27 b 44 s 61 9
|
||||
* 11 L 28 c 45 t 62 +
|
||||
* 12 M 29 d 46 u 63 /
|
||||
* 13 N 30 e 47 v
|
||||
* 14 O 31 f 48 w (pad) =
|
||||
* 15 P 32 g 49 x
|
||||
* 16 Q 33 h 50 y
|
||||
*
|
||||
* Special processing is performed if fewer than 24 bits are available
|
||||
* at the end of the data being encoded. A full encoding quantum is
|
||||
* always completed at the end of a quantity. When fewer than 24 input
|
||||
* bits are available in an input group, zero bits are added (on the
|
||||
* right) to form an integral number of 6-bit groups. Padding at the
|
||||
* end of the data is performed using the '=' character.
|
||||
*
|
||||
* Since all base64 input is an integral number of octets, only the
|
||||
* following cases can arise:
|
||||
*
|
||||
* (1) the final quantum of encoding input is an integral
|
||||
* multiple of 24 bits; here, the final unit of encoded
|
||||
* output will be an integral multiple of 4 characters
|
||||
* with no "=" padding,
|
||||
* (2) the final quantum of encoding input is exactly 8 bits;
|
||||
* here, the final unit of encoded output will be two
|
||||
* characters followed by two "=" padding characters, or
|
||||
* (3) the final quantum of encoding input is exactly 16 bits;
|
||||
* here, the final unit of encoded output will be three
|
||||
* characters followed by one "=" padding character.
|
||||
*/
|
||||
|
||||
int
|
||||
bson_b64_ntop (uint8_t const *src,
|
||||
size_t srclength,
|
||||
char *target,
|
||||
size_t targsize)
|
||||
{
|
||||
size_t datalength = 0;
|
||||
uint8_t input[3];
|
||||
uint8_t output[4];
|
||||
size_t i;
|
||||
|
||||
while (2 < srclength) {
|
||||
input[0] = *src++;
|
||||
input[1] = *src++;
|
||||
input[2] = *src++;
|
||||
srclength -= 3;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
output[3] = input[2] & 0x3f;
|
||||
Assert (output[0] < 64);
|
||||
Assert (output[1] < 64);
|
||||
Assert (output[2] < 64);
|
||||
Assert (output[3] < 64);
|
||||
|
||||
if (datalength + 4 > targsize) {
|
||||
return -1;
|
||||
}
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Base64[output[3]];
|
||||
}
|
||||
|
||||
/* Now we worry about padding. */
|
||||
if (0 != srclength) {
|
||||
/* Get what's left. */
|
||||
input[0] = input[1] = input[2] = '\0';
|
||||
|
||||
for (i = 0; i < srclength; i++) {
|
||||
input[i] = *src++;
|
||||
}
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
Assert (output[0] < 64);
|
||||
Assert (output[1] < 64);
|
||||
Assert (output[2] < 64);
|
||||
|
||||
if (datalength + 4 > targsize) {
|
||||
return -1;
|
||||
}
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
|
||||
if (srclength == 1) {
|
||||
target[datalength++] = Pad64;
|
||||
} else {
|
||||
target[datalength++] = Base64[output[2]];
|
||||
}
|
||||
target[datalength++] = Pad64;
|
||||
}
|
||||
|
||||
if (datalength >= targsize) {
|
||||
return -1;
|
||||
}
|
||||
target[datalength] = '\0'; /* Returned value doesn't count \0. */
|
||||
return (int) datalength;
|
||||
}
|
||||
|
||||
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
|
||||
The following encoding technique is taken from RFC 1521 by Borenstein
|
||||
and Freed. It is reproduced here in a slightly edited form for
|
||||
convenience.
|
||||
|
||||
A 65-character subset of US-ASCII is used, enabling 6 bits to be
|
||||
represented per printable character. (The extra 65th character, "=",
|
||||
is used to signify a special processing function.)
|
||||
|
||||
The encoding process represents 24-bit groups of input bits as output
|
||||
strings of 4 encoded characters. Proceeding from left to right, a
|
||||
24-bit input group is formed by concatenating 3 8-bit input groups.
|
||||
These 24 bits are then treated as 4 concatenated 6-bit groups, each
|
||||
of which is translated into a single digit in the base64 alphabet.
|
||||
|
||||
Each 6-bit group is used as an index into an array of 64 printable
|
||||
characters. The character referenced by the index is placed in the
|
||||
output string.
|
||||
|
||||
Table 1: The Base64 Alphabet
|
||||
|
||||
Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
0 A 17 R 34 i 51 z
|
||||
1 B 18 S 35 j 52 0
|
||||
2 C 19 T 36 k 53 1
|
||||
3 D 20 U 37 l 54 2
|
||||
4 E 21 V 38 m 55 3
|
||||
5 F 22 W 39 n 56 4
|
||||
6 G 23 X 40 o 57 5
|
||||
7 H 24 Y 41 p 58 6
|
||||
8 I 25 Z 42 q 59 7
|
||||
9 J 26 a 43 r 60 8
|
||||
10 K 27 b 44 s 61 9
|
||||
11 L 28 c 45 t 62 +
|
||||
12 M 29 d 46 u 63 /
|
||||
13 N 30 e 47 v
|
||||
14 O 31 f 48 w (pad) =
|
||||
15 P 32 g 49 x
|
||||
16 Q 33 h 50 y
|
||||
|
||||
Special processing is performed if fewer than 24 bits are available
|
||||
at the end of the data being encoded. A full encoding quantum is
|
||||
always completed at the end of a quantity. When fewer than 24 input
|
||||
bits are available in an input group, zero bits are added (on the
|
||||
right) to form an integral number of 6-bit groups. Padding at the
|
||||
end of the data is performed using the '=' character.
|
||||
|
||||
Since all base64 input is an integral number of octets, only the
|
||||
following cases can arise:
|
||||
|
||||
(1) the final quantum of encoding input is an integral
|
||||
multiple of 24 bits; here, the final unit of encoded
|
||||
output will be an integral multiple of 4 characters
|
||||
with no "=" padding,
|
||||
(2) the final quantum of encoding input is exactly 8 bits;
|
||||
here, the final unit of encoded output will be two
|
||||
characters followed by two "=" padding characters, or
|
||||
(3) the final quantum of encoding input is exactly 16 bits;
|
||||
here, the final unit of encoded output will be three
|
||||
characters followed by one "=" padding character.
|
||||
*/
|
||||
|
||||
/* skips all whitespace anywhere.
|
||||
converts characters, four at a time, starting at (or after)
|
||||
src from base - 64 numbers into three 8 bit bytes in the target area.
|
||||
it returns the number of data bytes stored at the target, or -1 on error.
|
||||
*/
|
||||
|
||||
static uint8_t mongoc_b64rmap[256];
|
||||
|
||||
static const uint8_t mongoc_b64rmap_special = 0xf0;
|
||||
static const uint8_t mongoc_b64rmap_end = 0xfd;
|
||||
static const uint8_t mongoc_b64rmap_space = 0xfe;
|
||||
static const uint8_t mongoc_b64rmap_invalid = 0xff;
|
||||
|
||||
/* initializing the reverse map isn't thread safe, do it in pthread_once */
|
||||
#if defined(BSON_OS_UNIX)
|
||||
#include <pthread.h>
|
||||
#define mongoc_common_once_t pthread_once_t
|
||||
#define mongoc_common_once pthread_once
|
||||
#define MONGOC_COMMON_ONCE_FUN(n) void n (void)
|
||||
#define MONGOC_COMMON_ONCE_RETURN return
|
||||
#define MONGOC_COMMON_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
#else
|
||||
#define mongoc_common_once_t INIT_ONCE
|
||||
#define MONGOC_COMMON_ONCE_INIT INIT_ONCE_STATIC_INIT
|
||||
#define mongoc_common_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL)
|
||||
#define MONGOC_COMMON_ONCE_FUN(n) \
|
||||
BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c)
|
||||
#define MONGOC_COMMON_ONCE_RETURN return true
|
||||
#endif
|
||||
|
||||
static MONGOC_COMMON_ONCE_FUN (bson_b64_initialize_rmap)
|
||||
{
|
||||
int i;
|
||||
unsigned char ch;
|
||||
|
||||
/* Null: end of string, stop parsing */
|
||||
mongoc_b64rmap[0] = mongoc_b64rmap_end;
|
||||
|
||||
for (i = 1; i < 256; ++i) {
|
||||
ch = (unsigned char) i;
|
||||
/* Whitespaces */
|
||||
if (isspace (ch))
|
||||
mongoc_b64rmap[i] = mongoc_b64rmap_space;
|
||||
/* Padding: stop parsing */
|
||||
else if (ch == Pad64)
|
||||
mongoc_b64rmap[i] = mongoc_b64rmap_end;
|
||||
/* Non-base64 char */
|
||||
else
|
||||
mongoc_b64rmap[i] = mongoc_b64rmap_invalid;
|
||||
}
|
||||
|
||||
/* Fill reverse mapping for base64 chars */
|
||||
for (i = 0; Base64[i] != '\0'; ++i)
|
||||
mongoc_b64rmap[(uint8_t) Base64[i]] = i;
|
||||
|
||||
MONGOC_COMMON_ONCE_RETURN;
|
||||
}
|
||||
|
||||
static int
|
||||
mongoc_b64_pton_do (char const *src, uint8_t *target, size_t targsize)
|
||||
{
|
||||
int tarindex, state, ch;
|
||||
uint8_t ofs;
|
||||
|
||||
state = 0;
|
||||
tarindex = 0;
|
||||
|
||||
while (1) {
|
||||
ch = *src++;
|
||||
ofs = mongoc_b64rmap[ch];
|
||||
|
||||
if (ofs >= mongoc_b64rmap_special) {
|
||||
/* Ignore whitespaces */
|
||||
if (ofs == mongoc_b64rmap_space)
|
||||
continue;
|
||||
/* End of base64 characters */
|
||||
if (ofs == mongoc_b64rmap_end)
|
||||
break;
|
||||
/* A non-base64 character. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if ((size_t) tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] = ofs << 2;
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if ((size_t) tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= ofs >> 4;
|
||||
target[tarindex + 1] = (ofs & 0x0f) << 4;
|
||||
tarindex++;
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if ((size_t) tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= ofs >> 2;
|
||||
target[tarindex + 1] = (ofs & 0x03) << 6;
|
||||
tarindex++;
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if ((size_t) tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= ofs;
|
||||
tarindex++;
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are done decoding Base-64 chars. Let's see if we ended
|
||||
* on a byte boundary, and/or with erroneous trailing characters.
|
||||
*/
|
||||
|
||||
if (ch == Pad64) { /* We got a pad char. */
|
||||
ch = *src++; /* Skip it, get next. */
|
||||
switch (state) {
|
||||
case 0: /* Invalid = in first position */
|
||||
case 1: /* Invalid = in second position */
|
||||
return (-1);
|
||||
|
||||
case 2: /* Valid, means one byte of info */
|
||||
/* Skip any number of spaces. */
|
||||
for ((void) NULL; ch != '\0'; ch = *src++)
|
||||
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
|
||||
break;
|
||||
/* Make sure there is another trailing = sign. */
|
||||
if (ch != Pad64)
|
||||
return (-1);
|
||||
ch = *src++; /* Skip the = */
|
||||
/* Fall through to "single trailing =" case. */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 3: /* Valid, means two bytes of info */
|
||||
/*
|
||||
* We know this char is an =. Is there anything but
|
||||
* whitespace after it?
|
||||
*/
|
||||
for ((void) NULL; ch != '\0'; ch = *src++)
|
||||
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Now make sure for cases 2 and 3 that the "extra"
|
||||
* bits that slopped past the last full byte were
|
||||
* zeros. If we don't check them, they become a
|
||||
* subliminal channel.
|
||||
*/
|
||||
if (target[tarindex] != 0)
|
||||
return (-1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We ended by seeing the end of the string. Make sure we
|
||||
* have no partial bytes lying around.
|
||||
*/
|
||||
if (state != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (tarindex);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
mongoc_b64_pton_len (char const *src)
|
||||
{
|
||||
int tarindex, state, ch;
|
||||
uint8_t ofs;
|
||||
|
||||
state = 0;
|
||||
tarindex = 0;
|
||||
|
||||
while (1) {
|
||||
ch = *src++;
|
||||
ofs = mongoc_b64rmap[ch];
|
||||
|
||||
if (ofs >= mongoc_b64rmap_special) {
|
||||
/* Ignore whitespaces */
|
||||
if (ofs == mongoc_b64rmap_space)
|
||||
continue;
|
||||
/* End of base64 characters */
|
||||
if (ofs == mongoc_b64rmap_end)
|
||||
break;
|
||||
/* A non-base64 character. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
tarindex++;
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
tarindex++;
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
tarindex++;
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are done decoding Base-64 chars. Let's see if we ended
|
||||
* on a byte boundary, and/or with erroneous trailing characters.
|
||||
*/
|
||||
|
||||
if (ch == Pad64) { /* We got a pad char. */
|
||||
ch = *src++; /* Skip it, get next. */
|
||||
switch (state) {
|
||||
case 0: /* Invalid = in first position */
|
||||
case 1: /* Invalid = in second position */
|
||||
return (-1);
|
||||
|
||||
case 2: /* Valid, means one byte of info */
|
||||
/* Skip any number of spaces. */
|
||||
for ((void) NULL; ch != '\0'; ch = *src++)
|
||||
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
|
||||
break;
|
||||
/* Make sure there is another trailing = sign. */
|
||||
if (ch != Pad64)
|
||||
return (-1);
|
||||
ch = *src++; /* Skip the = */
|
||||
/* Fall through to "single trailing =" case. */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 3: /* Valid, means two bytes of info */
|
||||
/*
|
||||
* We know this char is an =. Is there anything but
|
||||
* whitespace after it?
|
||||
*/
|
||||
for ((void) NULL; ch != '\0'; ch = *src++)
|
||||
if (mongoc_b64rmap[ch] != mongoc_b64rmap_space)
|
||||
return (-1);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We ended by seeing the end of the string. Make sure we
|
||||
* have no partial bytes lying around.
|
||||
*/
|
||||
if (state != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (tarindex);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bson_b64_pton (char const *src, uint8_t *target, size_t targsize)
|
||||
{
|
||||
static mongoc_common_once_t once = MONGOC_COMMON_ONCE_INIT;
|
||||
|
||||
mongoc_common_once (&once, bson_b64_initialize_rmap);
|
||||
|
||||
if (target)
|
||||
return mongoc_b64_pton_do (src, target, targsize);
|
||||
else
|
||||
return mongoc_b64_pton_len (src);
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2018-present MongoDB, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_MD5_PRIVATE_H
|
||||
#define COMMON_MD5_PRIVATE_H
|
||||
|
||||
|
||||
#if !defined(MONGOC_COMPILATION) && !defined(BSON_COMPILATION) && \
|
||||
!defined(BSON_INSIDE)
|
||||
#error "Only <mongoc/mongoc.h> or <bson/bson.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "bson/bson.h"
|
||||
|
||||
BSON_BEGIN_DECLS
|
||||
|
||||
void
|
||||
_bson_md5_init (bson_md5_t *pms);
|
||||
void
|
||||
_bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes);
|
||||
void
|
||||
_bson_md5_finish (bson_md5_t *pms, uint8_t digest[16]);
|
||||
|
||||
BSON_END_DECLS
|
||||
|
||||
#endif /* COMMON_MD5_PRIVATE_H */
|
395
contrib/mongoc/mongo-c-driver-1.13.1/src/common/common-md5.c
Normal file
395
contrib/mongoc/mongo-c-driver-1.13.1/src/common/common-md5.c
Normal file
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgement in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
L. Peter Deutsch
|
||||
ghost@aladdin.com
|
||||
|
||||
*/
|
||||
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
|
||||
/*
|
||||
Independent implementation of MD5 (RFC 1321).
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
copyrighted.
|
||||
|
||||
The original and principal author of md5.c is L. Peter Deutsch
|
||||
<ghost@aladdin.com>. Other authors are noted in the change history
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
|
||||
either statically or dynamically; added missing #include <string.h>
|
||||
in library.
|
||||
2002-03-11 lpd Corrected argument list for main(), and added int return
|
||||
type, in test program and T value program.
|
||||
2002-02-21 lpd Added missing #include <stdio.h> in test program.
|
||||
2000-07-03 lpd Patched to eliminate warnings about "constant is
|
||||
unsigned in ANSI C, signed in traditional"; made test program
|
||||
self-checking.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following MD5 implementation has been modified to use types as
|
||||
* specified in libbson.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "common-md5-private.h"
|
||||
|
||||
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#if BSON_BYTE_ORDER == BSON_BIG_ENDIAN
|
||||
#define BYTE_ORDER 1
|
||||
#else
|
||||
#define BYTE_ORDER -1
|
||||
#endif
|
||||
|
||||
#define T_MASK ((uint32_t) ~0)
|
||||
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
|
||||
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
|
||||
#define T3 0x242070db
|
||||
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
|
||||
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
|
||||
#define T6 0x4787c62a
|
||||
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
|
||||
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
|
||||
#define T9 0x698098d8
|
||||
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
|
||||
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
|
||||
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
|
||||
#define T13 0x6b901122
|
||||
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
|
||||
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
|
||||
#define T16 0x49b40821
|
||||
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
|
||||
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
|
||||
#define T19 0x265e5a51
|
||||
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
|
||||
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
|
||||
#define T22 0x02441453
|
||||
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
|
||||
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
|
||||
#define T25 0x21e1cde6
|
||||
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
|
||||
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
|
||||
#define T28 0x455a14ed
|
||||
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
|
||||
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
|
||||
#define T31 0x676f02d9
|
||||
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
|
||||
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
|
||||
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
|
||||
#define T35 0x6d9d6122
|
||||
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
|
||||
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
|
||||
#define T38 0x4bdecfa9
|
||||
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
|
||||
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
|
||||
#define T41 0x289b7ec6
|
||||
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
|
||||
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
|
||||
#define T44 0x04881d05
|
||||
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
|
||||
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
|
||||
#define T47 0x1fa27cf8
|
||||
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
|
||||
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
|
||||
#define T50 0x432aff97
|
||||
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
|
||||
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
|
||||
#define T53 0x655b59c3
|
||||
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
|
||||
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
|
||||
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
|
||||
#define T57 0x6fa87e4f
|
||||
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
|
||||
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
|
||||
#define T60 0x4e0811a1
|
||||
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
|
||||
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
|
||||
#define T63 0x2ad7d2bb
|
||||
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
|
||||
|
||||
|
||||
static void
|
||||
bson_md5_process (bson_md5_t *md5, const uint8_t *data)
|
||||
{
|
||||
uint32_t a = md5->abcd[0];
|
||||
uint32_t b = md5->abcd[1];
|
||||
uint32_t c = md5->abcd[2];
|
||||
uint32_t d = md5->abcd[3];
|
||||
uint32_t t;
|
||||
|
||||
#if BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
uint32_t X[16];
|
||||
#else
|
||||
/* Define storage for little-endian or both types of CPUs. */
|
||||
uint32_t xbuf[16];
|
||||
const uint32_t *X;
|
||||
#endif
|
||||
|
||||
{
|
||||
#if BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static const int w = 1;
|
||||
|
||||
if (*((const uint8_t *) &w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (const uint8_t *) 0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-align"
|
||||
#endif
|
||||
X = (const uint32_t *) data;
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
} else {
|
||||
/* not aligned */
|
||||
memcpy (xbuf, data, sizeof (xbuf));
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const uint8_t *xp = data;
|
||||
int i;
|
||||
|
||||
#if BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
#else
|
||||
#define xbuf X /* (static only) */
|
||||
#endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
|
||||
/* Round 1. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + F (b, c, d) + X[k] + Ti; \
|
||||
a = ROTATE_LEFT (t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET (a, b, c, d, 0, 7, T1);
|
||||
SET (d, a, b, c, 1, 12, T2);
|
||||
SET (c, d, a, b, 2, 17, T3);
|
||||
SET (b, c, d, a, 3, 22, T4);
|
||||
SET (a, b, c, d, 4, 7, T5);
|
||||
SET (d, a, b, c, 5, 12, T6);
|
||||
SET (c, d, a, b, 6, 17, T7);
|
||||
SET (b, c, d, a, 7, 22, T8);
|
||||
SET (a, b, c, d, 8, 7, T9);
|
||||
SET (d, a, b, c, 9, 12, T10);
|
||||
SET (c, d, a, b, 10, 17, T11);
|
||||
SET (b, c, d, a, 11, 22, T12);
|
||||
SET (a, b, c, d, 12, 7, T13);
|
||||
SET (d, a, b, c, 13, 12, T14);
|
||||
SET (c, d, a, b, 14, 17, T15);
|
||||
SET (b, c, d, a, 15, 22, T16);
|
||||
#undef SET
|
||||
|
||||
/* Round 2. */
|
||||
/* Let [abcd k s i] denote the operation
|
||||
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + G (b, c, d) + X[k] + Ti; \
|
||||
a = ROTATE_LEFT (t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET (a, b, c, d, 1, 5, T17);
|
||||
SET (d, a, b, c, 6, 9, T18);
|
||||
SET (c, d, a, b, 11, 14, T19);
|
||||
SET (b, c, d, a, 0, 20, T20);
|
||||
SET (a, b, c, d, 5, 5, T21);
|
||||
SET (d, a, b, c, 10, 9, T22);
|
||||
SET (c, d, a, b, 15, 14, T23);
|
||||
SET (b, c, d, a, 4, 20, T24);
|
||||
SET (a, b, c, d, 9, 5, T25);
|
||||
SET (d, a, b, c, 14, 9, T26);
|
||||
SET (c, d, a, b, 3, 14, T27);
|
||||
SET (b, c, d, a, 8, 20, T28);
|
||||
SET (a, b, c, d, 13, 5, T29);
|
||||
SET (d, a, b, c, 2, 9, T30);
|
||||
SET (c, d, a, b, 7, 14, T31);
|
||||
SET (b, c, d, a, 12, 20, T32);
|
||||
#undef SET
|
||||
|
||||
/* Round 3. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + H (b, c, d) + X[k] + Ti; \
|
||||
a = ROTATE_LEFT (t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET (a, b, c, d, 5, 4, T33);
|
||||
SET (d, a, b, c, 8, 11, T34);
|
||||
SET (c, d, a, b, 11, 16, T35);
|
||||
SET (b, c, d, a, 14, 23, T36);
|
||||
SET (a, b, c, d, 1, 4, T37);
|
||||
SET (d, a, b, c, 4, 11, T38);
|
||||
SET (c, d, a, b, 7, 16, T39);
|
||||
SET (b, c, d, a, 10, 23, T40);
|
||||
SET (a, b, c, d, 13, 4, T41);
|
||||
SET (d, a, b, c, 0, 11, T42);
|
||||
SET (c, d, a, b, 3, 16, T43);
|
||||
SET (b, c, d, a, 6, 23, T44);
|
||||
SET (a, b, c, d, 9, 4, T45);
|
||||
SET (d, a, b, c, 12, 11, T46);
|
||||
SET (c, d, a, b, 15, 16, T47);
|
||||
SET (b, c, d, a, 2, 23, T48);
|
||||
#undef SET
|
||||
|
||||
/* Round 4. */
|
||||
/* Let [abcd k s t] denote the operation
|
||||
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
|
||||
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||
#define SET(a, b, c, d, k, s, Ti) \
|
||||
t = a + I (b, c, d) + X[k] + Ti; \
|
||||
a = ROTATE_LEFT (t, s) + b
|
||||
/* Do the following 16 operations. */
|
||||
SET (a, b, c, d, 0, 6, T49);
|
||||
SET (d, a, b, c, 7, 10, T50);
|
||||
SET (c, d, a, b, 14, 15, T51);
|
||||
SET (b, c, d, a, 5, 21, T52);
|
||||
SET (a, b, c, d, 12, 6, T53);
|
||||
SET (d, a, b, c, 3, 10, T54);
|
||||
SET (c, d, a, b, 10, 15, T55);
|
||||
SET (b, c, d, a, 1, 21, T56);
|
||||
SET (a, b, c, d, 8, 6, T57);
|
||||
SET (d, a, b, c, 15, 10, T58);
|
||||
SET (c, d, a, b, 6, 15, T59);
|
||||
SET (b, c, d, a, 13, 21, T60);
|
||||
SET (a, b, c, d, 4, 6, T61);
|
||||
SET (d, a, b, c, 11, 10, T62);
|
||||
SET (c, d, a, b, 2, 15, T63);
|
||||
SET (b, c, d, a, 9, 21, T64);
|
||||
#undef SET
|
||||
|
||||
/* Then perform the following additions. (That is increment each
|
||||
of the four registers by the value it had before this block
|
||||
was started.) */
|
||||
md5->abcd[0] += a;
|
||||
md5->abcd[1] += b;
|
||||
md5->abcd[2] += c;
|
||||
md5->abcd[3] += d;
|
||||
}
|
||||
|
||||
void
|
||||
_bson_md5_init (bson_md5_t *pms)
|
||||
{
|
||||
pms->count[0] = pms->count[1] = 0;
|
||||
pms->abcd[0] = 0x67452301;
|
||||
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
|
||||
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
|
||||
pms->abcd[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void
|
||||
_bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes)
|
||||
{
|
||||
const uint8_t *p = data;
|
||||
int left = nbytes;
|
||||
int offset = (pms->count[0] >> 3) & 63;
|
||||
uint32_t nbits = (uint32_t) (nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
|
||||
memcpy (pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
bson_md5_process (pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
bson_md5_process (pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
memcpy (pms->buf, p, left);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_bson_md5_finish (bson_md5_t *pms, uint8_t digest[16])
|
||||
{
|
||||
static const uint8_t pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint8_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (uint8_t) (pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
_bson_md5_append (pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
_bson_md5_append (pms, data, sizeof (data));
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (uint8_t) (pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013-present MongoDB, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_THREAD_PRIVATE_H
|
||||
#define COMMON_THREAD_PRIVATE_H
|
||||
|
||||
#if !defined(MONGOC_COMPILATION) && !defined(BSON_COMPILATION) && \
|
||||
!defined(BSON_INSIDE)
|
||||
#error "Only <mongoc/mongoc.h> or <bson/bson.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include "bson/bson-compat.h"
|
||||
#include "bson/bson-config.h"
|
||||
#include "bson/bson-macros.h"
|
||||
|
||||
BSON_BEGIN_DECLS
|
||||
|
||||
#if defined(BSON_OS_UNIX)
|
||||
#include <pthread.h>
|
||||
#define BSON_ONCE_FUN(n) void n (void)
|
||||
#define BSON_ONCE_RETURN return
|
||||
#define BSON_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
#define bson_mutex_destroy pthread_mutex_destroy
|
||||
#define bson_mutex_init(_n) pthread_mutex_init ((_n), NULL)
|
||||
#define bson_mutex_lock pthread_mutex_lock
|
||||
#define bson_mutex_t pthread_mutex_t
|
||||
#define bson_mutex_unlock pthread_mutex_unlock
|
||||
#define bson_once pthread_once
|
||||
#define bson_once_t pthread_once_t
|
||||
#define bson_thread_create(_t, _f, _d) pthread_create ((_t), NULL, (_f), (_d))
|
||||
#define bson_thread_join(_n) pthread_join ((_n), NULL)
|
||||
#define bson_thread_t pthread_t
|
||||
#else
|
||||
#define BSON_ONCE_FUN(n) \
|
||||
BOOL CALLBACK n (PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c)
|
||||
#define BSON_ONCE_INIT INIT_ONCE_STATIC_INIT
|
||||
#define BSON_ONCE_RETURN return true
|
||||
#define bson_mutex_destroy DeleteCriticalSection
|
||||
#define bson_mutex_init InitializeCriticalSection
|
||||
#define bson_mutex_lock EnterCriticalSection
|
||||
#define bson_mutex_t CRITICAL_SECTION
|
||||
#define bson_mutex_unlock LeaveCriticalSection
|
||||
#define bson_once(o, c) InitOnceExecuteOnce (o, c, NULL, NULL)
|
||||
#define bson_once_t INIT_ONCE
|
||||
#define bson_thread_create(_t, _f, _d) \
|
||||
(!(*(_t) = CreateThread (NULL, 0, (void *) _f, _d, 0, NULL)))
|
||||
#define bson_thread_join(_n) WaitForSingleObject ((_n), INFINITE)
|
||||
#define bson_thread_t HANDLE
|
||||
#endif
|
||||
|
||||
BSON_END_DECLS
|
||||
|
||||
#endif /* COMMON_THREAD_PRIVATE_H */
|
414
contrib/mongoc/mongo-c-driver-1.13.1/src/libbson/CMakeLists.txt
Normal file
414
contrib/mongoc/mongo-c-driver-1.13.1/src/libbson/CMakeLists.txt
Normal file
@@ -0,0 +1,414 @@
|
||||
cmake_minimum_required (VERSION 3.1)
|
||||
|
||||
project (libbson C)
|
||||
|
||||
# In the future we may need to check whether static dependencies are
|
||||
# available. For now, AUTO means ON.
|
||||
if (ENABLE_TESTS AND NOT ENABLE_STATIC MATCHES "ON|AUTO")
|
||||
message (FATAL_ERROR "-DENABLE_STATIC=OFF also requires -DENABLE_TESTS=OFF")
|
||||
endif ()
|
||||
|
||||
include (CheckFunctionExists)
|
||||
include (CheckIncludeFile)
|
||||
include (CheckStructHasMember)
|
||||
include (CheckSymbolExists)
|
||||
include (TestBigEndian)
|
||||
include (InstallRequiredSystemLibraries)
|
||||
|
||||
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/build/cmake)
|
||||
|
||||
# Set BSON_MAJOR_VERSION, BSON_MINOR_VERSION, etc.
|
||||
set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/../../build/cmake)
|
||||
include (LoadVersion)
|
||||
LoadVersion (${PROJECT_SOURCE_DIR}/../../VERSION_CURRENT BSON)
|
||||
LoadVersion (${PROJECT_SOURCE_DIR}/../../VERSION_RELEASED BSON_RELEASED)
|
||||
|
||||
message ("libbson version (from VERSION_CURRENT file): ${BSON_VERSION}")
|
||||
if (NOT ${BSON_VERSION} STREQUAL ${BSON_RELEASED_VERSION})
|
||||
message ("libbson previous release (from VERSION_RELEASED file): ${BSON_RELEASED_VERSION}")
|
||||
endif ()
|
||||
|
||||
set (BSON_API_VERSION 1.0)
|
||||
|
||||
set (CPACK_PACKAGE_VERSION_MAJOR ${BSON_MAJOR_VERSION})
|
||||
set (CPACK_PACKAGE_VERSION_MINOR ${BSON_MINOR_VERSION})
|
||||
|
||||
include (CPack)
|
||||
TEST_BIG_ENDIAN (BSON_BIG_ENDIAN)
|
||||
|
||||
#librt needed on linux for clock_gettime
|
||||
find_library (RT_LIBRARY rt)
|
||||
if (RT_LIBRARY)
|
||||
#set required libraries for CHECK_FUNCTION_EXISTS
|
||||
set (CMAKE_REQUIRED_LIBRARIES ${RT_LIBRARY})
|
||||
set (BSON_LIBRARIES ${BSON_LIBRARIES} ${RT_LIBRARY})
|
||||
endif ()
|
||||
|
||||
# See https://public.kitware.com/Bug/view.php?id=15659
|
||||
CHECK_SYMBOL_EXISTS (snprintf stdio.h BSON_HAVE_SNPRINTF)
|
||||
if (NOT BSON_HAVE_SNPRINTF)
|
||||
set (BSON_HAVE_SNPRINTF 0)
|
||||
else ()
|
||||
set (BSON_HAVE_SNPRINTF 1)
|
||||
endif ()
|
||||
|
||||
CHECK_FUNCTION_EXISTS (reallocf BSON_HAVE_REALLOCF)
|
||||
if (NOT BSON_HAVE_REALLOCF)
|
||||
set (BSON_HAVE_REALLOCF 0)
|
||||
endif ()
|
||||
|
||||
CHECK_STRUCT_HAS_MEMBER ("struct timespec" tv_sec time.h BSON_HAVE_TIMESPEC)
|
||||
if (NOT BSON_HAVE_TIMESPEC)
|
||||
message (STATUS " no timespec struct")
|
||||
set (BSON_HAVE_TIMESPEC 0)
|
||||
else ()
|
||||
message (STATUS " struct timespec found")
|
||||
set (BSON_HAVE_TIMESPEC 1)
|
||||
endif ()
|
||||
|
||||
CHECK_SYMBOL_EXISTS (gmtime_r time.h BSON_HAVE_GMTIME_R)
|
||||
if (NOT BSON_HAVE_GMTIME_R)
|
||||
set (BSON_HAVE_GMTIME_R 0)
|
||||
else ()
|
||||
set (BSON_HAVE_GMTIME_R 1)
|
||||
endif ()
|
||||
|
||||
CHECK_FUNCTION_EXISTS (rand_r BSON_HAVE_RAND_R)
|
||||
if (NOT BSON_HAVE_RAND_R)
|
||||
set (BSON_HAVE_RAND_R 0)
|
||||
else ()
|
||||
set (BSON_HAVE_RAND_R 1)
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
set (BSON_OS 2)
|
||||
else ()
|
||||
set (BSON_OS 1)
|
||||
endif ()
|
||||
|
||||
include (CheckIncludeFiles)
|
||||
|
||||
CHECK_INCLUDE_FILE (strings.h BSON_HAVE_STRINGS_H)
|
||||
if (NOT BSON_HAVE_STRINGS_H)
|
||||
set (BSON_HAVE_STRINGS_H 0)
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
set (BSON_HAVE_CLOCK_GETTIME 0)
|
||||
set (BSON_HAVE_STDBOOL_H 0)
|
||||
set (BSON_HAVE_STRNLEN 0)
|
||||
set (BSON_HAVE_SYSCALL_TID 0)
|
||||
else ()
|
||||
check_symbol_exists (clock_gettime time.h BSON_HAVE_CLOCK_GETTIME)
|
||||
if (NOT BSON_HAVE_CLOCK_GETTIME)
|
||||
set (BSON_HAVE_CLOCK_GETTIME 0)
|
||||
endif ()
|
||||
check_symbol_exists (strnlen string.h BSON_HAVE_STRNLEN)
|
||||
if (NOT BSON_HAVE_STRNLEN)
|
||||
set (BSON_HAVE_STRNLEN 0)
|
||||
endif ()
|
||||
CHECK_INCLUDE_FILE (stdbool.h BSON_HAVE_STDBOOL_H)
|
||||
if (NOT BSON_HAVE_STDBOOL_H)
|
||||
set (BSON_HAVE_STDBOOL_H 0)
|
||||
endif ()
|
||||
CHECK_SYMBOL_EXISTS (SYS_gettid sys/syscall.h BSON_HAVE_SYSCALL_TID)
|
||||
check_symbol_exists (syscall unistd.h _TMP_HAVE_SYSCALL)
|
||||
if (NOT BSON_HAVE_SYSCALL_TID OR NOT _TMP_HAVE_SYSCALL OR APPLE OR ANDROID)
|
||||
set (BSON_HAVE_SYSCALL_TID 0)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (BSON_BIG_ENDIAN)
|
||||
set (BSON_BYTE_ORDER 4321)
|
||||
else ()
|
||||
set (BSON_BYTE_ORDER 1234)
|
||||
endif ()
|
||||
|
||||
include (CheckAtomics)
|
||||
|
||||
configure_file (
|
||||
"${PROJECT_SOURCE_DIR}/src/bson/bson-config.h.in"
|
||||
"${PROJECT_BINARY_DIR}/src/bson/bson-config.h"
|
||||
)
|
||||
|
||||
configure_file (
|
||||
"${PROJECT_SOURCE_DIR}/src/bson/bson-version.h.in"
|
||||
"${PROJECT_BINARY_DIR}/src/bson/bson-version.h"
|
||||
)
|
||||
|
||||
if (ENABLE_APPLE_FRAMEWORK)
|
||||
configure_file (
|
||||
"${PROJECT_SOURCE_DIR}/src/bson/modules/module.modulemap.in"
|
||||
"${PROJECT_BINARY_DIR}/src/bson/modules/module.modulemap"
|
||||
)
|
||||
endif ()
|
||||
|
||||
include_directories ("${PROJECT_BINARY_DIR}/src")
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/src")
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/../../src/common")
|
||||
|
||||
if (APPLE)
|
||||
cmake_policy (SET CMP0042 OLD)
|
||||
endif ()
|
||||
|
||||
include (MaintainerFlags)
|
||||
|
||||
if (ENABLE_COVERAGE)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g --coverage")
|
||||
endif ()
|
||||
|
||||
set (SOURCES
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bcon.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-atomic.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-clock.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-context.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-decimal128.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-error.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-fnv.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-iso8601.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-iter.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-json.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-keys.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-md5.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-memory.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-oid.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-reader.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-string.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-timegm.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-utf8.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-value.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-version-functions.c
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-writer.c
|
||||
${PROJECT_SOURCE_DIR}/src/jsonsl/jsonsl.c
|
||||
${PROJECT_SOURCE_DIR}/../../src/common/common-b64.c
|
||||
${PROJECT_SOURCE_DIR}/../../src/common/common-md5.c
|
||||
)
|
||||
|
||||
set (HEADERS
|
||||
${PROJECT_BINARY_DIR}/src/bson/bson-config.h
|
||||
${PROJECT_BINARY_DIR}/src/bson/bson-version.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bcon.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-atomic.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-clock.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-compat.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-context.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-decimal128.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-endian.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-error.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-iter.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-json.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-keys.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-macros.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-md5.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-memory.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-oid.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-reader.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-string.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-types.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-utf8.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-value.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-version-functions.h
|
||||
${PROJECT_SOURCE_DIR}/src/bson/bson-writer.h
|
||||
)
|
||||
|
||||
set (HEADERS_FORWARDING
|
||||
${PROJECT_SOURCE_DIR}/src/bson/forwarding/bson.h
|
||||
)
|
||||
|
||||
add_library (bson_shared SHARED ${SOURCES} ${HEADERS} ${HEADERS_FORWARDING})
|
||||
set (CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set_target_properties (bson_shared PROPERTIES COMPILE_DEFINITIONS "BSON_COMPILATION;JSONSL_PARSE_NAN")
|
||||
set_target_properties (bson_shared PROPERTIES VERSION 0.0.0 SOVERSION 0)
|
||||
set_target_properties (bson_shared PROPERTIES OUTPUT_NAME "bson-${BSON_API_VERSION}" PREFIX "lib")
|
||||
|
||||
if (ENABLE_APPLE_FRAMEWORK)
|
||||
set_target_properties(bson_shared PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
MACOSX_FRAMEWORK_BUNDLE_VERSION ${MONGOC_VERSION}
|
||||
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${MONGOC_VERSION}
|
||||
MACOSX_FRAMEWORK_IDENTIFIER org.mongodb.bson
|
||||
OUTPUT_NAME "bson"
|
||||
PUBLIC_HEADER "${HEADERS}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (RT_LIBRARY)
|
||||
target_link_libraries (bson_shared ${RT_LIBRARY})
|
||||
endif ()
|
||||
|
||||
find_library (M_LIBRARY m)
|
||||
if (M_LIBRARY)
|
||||
target_link_libraries (bson_shared ${M_LIBRARY})
|
||||
set (BSON_LIBRARIES ${BSON_LIBRARIES} ${M_LIBRARY})
|
||||
endif ()
|
||||
|
||||
set (THREADS_PREFER_PTHREAD_FLAG 1)
|
||||
find_package (Threads REQUIRED)
|
||||
target_link_libraries (bson_shared Threads::Threads)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set (BSON_LIBRARIES ${BSON_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
# gethostbyname
|
||||
target_link_libraries (bson_shared ws2_32)
|
||||
# Can't find_library () system dependencies
|
||||
# must be handled specially since we can't resolve them
|
||||
set (BSON_SYSTEM_LIBRARIES ${BSON_SYSTEM_LIBRARIES} ws2_32)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_STATIC MATCHES "ON|AUTO")
|
||||
add_library (bson_static STATIC ${SOURCES} ${HEADERS} ${HEADERS_FORWARDING})
|
||||
set_target_properties (bson_static PROPERTIES COMPILE_DEFINITIONS "BSON_COMPILATION;BSON_STATIC;JSONSL_PARSE_NAN")
|
||||
set_target_properties (bson_static PROPERTIES VERSION 0.0.0)
|
||||
set_target_properties (bson_static PROPERTIES OUTPUT_NAME "bson-static-${BSON_API_VERSION}")
|
||||
target_link_libraries (bson_static Threads::Threads)
|
||||
if (RT_LIBRARY)
|
||||
target_link_libraries (bson_static ${RT_LIBRARY})
|
||||
endif ()
|
||||
if (M_LIBRARY)
|
||||
target_link_libraries (bson_static ${M_LIBRARY})
|
||||
endif ()
|
||||
if (NOT UNIX)
|
||||
# gethostbyname
|
||||
target_link_libraries (bson_static ws2_32)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
function (add_example bin src)
|
||||
set (BSON_EXAMPLE_SOURCES ${PROJECT_SOURCE_DIR}/${src})
|
||||
add_executable (${bin} ${BSON_EXAMPLE_SOURCES})
|
||||
|
||||
# Link against the shared lib like normal apps
|
||||
target_link_libraries (${bin} bson_shared)
|
||||
|
||||
set (EXAMPLES ${EXAMPLES} ${bin})
|
||||
endfunction ()
|
||||
|
||||
if (ENABLE_EXAMPLES)
|
||||
add_example (bcon-col-view examples/bcon-col-view.c)
|
||||
add_example (bcon-speed examples/bcon-speed.c)
|
||||
add_example (bson-metrics examples/bson-metrics.c)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries (bson-metrics m)
|
||||
add_example (bson-streaming-reader examples/bson-streaming-reader.c)
|
||||
endif ()
|
||||
add_example (bson-to-json examples/bson-to-json.c)
|
||||
add_example (bson-validate examples/bson-validate.c)
|
||||
add_example (json-to-bson examples/json-to-bson.c)
|
||||
endif () # ENABLE_EXAMPLES
|
||||
|
||||
set (BSON_HEADER_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}/libbson-${BSON_API_VERSION}"
|
||||
)
|
||||
|
||||
install (
|
||||
TARGETS bson_shared ${EXAMPLES}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
if (ENABLE_STATIC MATCHES "ON|AUTO")
|
||||
install (
|
||||
TARGETS bson_static ${EXAMPLES}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif ()
|
||||
install (
|
||||
FILES ${HEADERS}
|
||||
DESTINATION "${BSON_HEADER_INSTALL_DIR}/bson"
|
||||
)
|
||||
install (
|
||||
FILES ${HEADERS_FORWARDING}
|
||||
DESTINATION "${BSON_HEADER_INSTALL_DIR}"
|
||||
)
|
||||
|
||||
if (ENABLE_APPLE_FRAMEWORK)
|
||||
install (
|
||||
FILES "${PROJECT_BINARY_DIR}/src/bson/modules/module.modulemap"
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}/bson.framework/Modules/"
|
||||
)
|
||||
endif ()
|
||||
|
||||
set (LIBBSON_LIBRARIES "")
|
||||
foreach (_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${BSON_LIBRARIES})
|
||||
if (_lib MATCHES ".*/.*" OR _lib MATCHES "^-")
|
||||
set (LIBBSON_LIBRARIES "${LIBBSON_LIBRARIES} ${_lib}")
|
||||
else ()
|
||||
set (LIBBSON_LIBRARIES "${LIBBSON_LIBRARIES} -l${_lib}")
|
||||
endif ()
|
||||
endforeach ()
|
||||
# System dependencies don't match the above regexs, but also don't want the -l
|
||||
foreach (_lib ${BSON_SYSTEM_LIBRARIES})
|
||||
set (LIBBSON_LIBRARIES "${LIBBSON_LIBRARIES} ${_lib}")
|
||||
endforeach ()
|
||||
|
||||
set (VERSION "${BSON_VERSION}")
|
||||
set (prefix "${CMAKE_INSTALL_PREFIX}")
|
||||
set (libdir "\${prefix}/lib")
|
||||
configure_file (
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/libbson-1.0.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/libbson-1.0.pc
|
||||
@ONLY)
|
||||
|
||||
install (
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/libbson-1.0.pc
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
)
|
||||
|
||||
if (ENABLE_STATIC MATCHES "ON|AUTO")
|
||||
configure_file (
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/libbson-static-1.0.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/libbson-static-1.0.pc
|
||||
@ONLY)
|
||||
|
||||
install (
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/libbson-static-1.0.pc
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/pkgconfig
|
||||
)
|
||||
endif ()
|
||||
|
||||
include (build/cmake/BSONPackage.cmake)
|
||||
|
||||
if (ENABLE_MAN_PAGES STREQUAL ON OR ENABLE_HTML_DOCS STREQUAL ON)
|
||||
find_package (Sphinx REQUIRED)
|
||||
add_subdirectory (doc)
|
||||
add_custom_target (bson-doc
|
||||
ALL
|
||||
DEPENDS
|
||||
$<$<STREQUAL:"${ENABLE_MAN_PAGES}","ON">:bson-man>
|
||||
$<$<STREQUAL:"${ENABLE_HTML_DOCS}","ON">:bson-html>
|
||||
)
|
||||
endif ()
|
||||
|
||||
add_subdirectory (build)
|
||||
# sub-directory 'doc' was already included above
|
||||
add_subdirectory (examples)
|
||||
add_subdirectory (src)
|
||||
add_subdirectory (tests)
|
||||
|
||||
set_local_dist (src_libbson_DIST_local
|
||||
CMakeLists.txt
|
||||
NEWS
|
||||
THIRD_PARTY_NOTICES
|
||||
)
|
||||
|
||||
set (src_libbson_DIST
|
||||
${src_libbson_DIST_local}
|
||||
${src_libbson_build_DIST}
|
||||
${src_libbson_doc_DIST}
|
||||
${src_libbson_examples_DIST}
|
||||
${src_libbson_src_DIST}
|
||||
${src_libbson_tests_DIST}
|
||||
PARENT_SCOPE
|
||||
)
|
1328
contrib/mongoc/mongo-c-driver-1.13.1/src/libbson/NEWS
Normal file
1328
contrib/mongoc/mongo-c-driver-1.13.1/src/libbson/NEWS
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
Libbson uses third-party libraries distributed under different licenses.
|
||||
|
||||
License notice for jsonsl
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2012-2015 M. Nunberg, mnunberg@haskalah.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
License notice for bson-fnv-private.h, bson-fnv.c and test-fnv.c
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Please do not copyright this code. This code is in the public domain.
|
||||
|
||||
LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
|
||||
EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
By:
|
||||
chongo <Landon Curt Noll> /\oo/\
|
||||
http://www.isthe.com/chongo/
|
@@ -0,0 +1,36 @@
|
||||
include (SphinxBuild)
|
||||
|
||||
if (ENABLE_HTML_DOCS)
|
||||
sphinx_build_html (bson-html libbson)
|
||||
set (src_libbson_doc_DIST_htmls ${doc_DIST_htmls})
|
||||
endif ()
|
||||
|
||||
if (ENABLE_MAN_PAGES)
|
||||
sphinx_build_man (bson-man)
|
||||
set (src_libbson_doc_DIST_mans ${doc_DIST_mans})
|
||||
endif ()
|
||||
|
||||
add_subdirectory (html)
|
||||
add_subdirectory (man)
|
||||
|
||||
file (GLOB src_libbson_doc_DIST_rsts RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.rst)
|
||||
|
||||
extra_dist_generated (
|
||||
${src_libbson_doc_DIST_htmls}
|
||||
${src_libbson_doc_DIST_mans}
|
||||
)
|
||||
|
||||
set_local_dist (src_libbson_doc_DIST_local
|
||||
CMakeLists.txt
|
||||
${src_libbson_doc_DIST_rsts}
|
||||
conf.py
|
||||
)
|
||||
|
||||
set (src_libbson_doc_DIST
|
||||
${src_libbson_doc_DIST_local}
|
||||
${src_libbson_doc_html_DIST}
|
||||
${src_libbson_doc_man_DIST}
|
||||
${src_libbson_doc_mongoc_DIST}
|
||||
${src_libbson_doc_mongoc-theme_DIST}
|
||||
PARENT_SCOPE
|
||||
)
|
27
contrib/mongoc/mongo-c-driver-1.13.1/src/libbson/doc/api.rst
Normal file
27
contrib/mongoc/mongo-c-driver-1.13.1/src/libbson/doc/api.rst
Normal file
@@ -0,0 +1,27 @@
|
||||
API Reference
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
:maxdepth: 2
|
||||
|
||||
bson_t
|
||||
bson_context_t
|
||||
bson_decimal128_t
|
||||
bson_error_t
|
||||
bson_iter_t
|
||||
bson_json_reader_t
|
||||
bson_md5_t
|
||||
bson_oid_t
|
||||
bson_reader_t
|
||||
character_and_string_routines
|
||||
bson_string_t
|
||||
bson_subtype_t
|
||||
bson_type_t
|
||||
bson_unichar_t
|
||||
bson_value_t
|
||||
bson_visitor_t
|
||||
bson_writer_t
|
||||
bson_get_monotonic_time
|
||||
bson_memory
|
||||
version
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_array
|
||||
|
||||
bson_append_array()
|
||||
===================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_ARRAY(b, key, val) \
|
||||
bson_append_array (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_array (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const bson_t *array);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``array``: A :symbol:`bson_t`.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_array()` function shall append ``array`` to ``bson`` using the specified key. The type of the field will be an array, but it is the responsibility of the caller to ensure that the keys of ``array`` are properly formatted with string keys such as "0", "1", "2" and so forth.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function fails if appending the array grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,39 @@
|
||||
:man_page: bson_append_array_begin
|
||||
|
||||
bson_append_array_begin()
|
||||
=========================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_ARRAY_BEGIN(b, key, child) \
|
||||
bson_append_array_begin (b, key, (int) strlen (key), child)
|
||||
|
||||
bool
|
||||
bson_append_array_begin (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
bson_t *child);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: A string containing the name for the key.
|
||||
* ``key_length``: The length of ``key`` or -1 to call ``strlen()``.
|
||||
* ``child``: A :symbol:`bson_t`.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_array_begin()` function shall begin appending an array field to ``bson``. This allows for incrementally building a sub-array. Doing so will generally yield better performance as you will serialize to a single buffer. When done building the sub-array, the caller *MUST* call :symbol:`bson_append_array_end()`.
|
||||
|
||||
For generating array element keys, see :symbol:`bson_uint32_to_string`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the array grows ``bson`` larger than INT32_MAX.
|
||||
|
@@ -0,0 +1,28 @@
|
||||
:man_page: bson_append_array_end
|
||||
|
||||
bson_append_array_end()
|
||||
=======================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
bool
|
||||
bson_append_array_end (bson_t *bson, bson_t *child);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``child``: The :symbol:`bson_t` initialized in a call to :symbol:`bson_append_array_begin()`.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_array_end()` function shall complete the appending of an array field started with :symbol:`bson_append_array_begin()`. ``child`` is invalid after calling this function.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if successful.
|
@@ -0,0 +1,40 @@
|
||||
:man_page: bson_append_binary
|
||||
|
||||
bson_append_binary()
|
||||
====================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_BINARY(b, key, subtype, val, len) \
|
||||
bson_append_binary (b, key, (int) strlen (key), subtype, val, len)
|
||||
|
||||
bool
|
||||
bson_append_binary (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
bson_subtype_t subtype,
|
||||
const uint8_t *binary,
|
||||
uint32_t length);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: The key name.
|
||||
* ``key_length``: The length of ``key`` in bytes or -1 to use strlen().
|
||||
* ``subtype``: A bson_subtype_t indicating the binary subtype.
|
||||
* ``binary``: A buffer to embed as binary data. Must not be ``NULL``.
|
||||
* ``length``: The length of ``buffer`` in bytes.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_binary()` function shall append a new element to ``bson`` containing the binary data provided.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``binary`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,33 @@
|
||||
:man_page: bson_append_bool
|
||||
|
||||
bson_append_bool()
|
||||
==================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_BOOL(b, key, val) \
|
||||
bson_append_bool (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_bool (bson_t *bson, const char *key, int key_length, bool value);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: The name of the field.
|
||||
* ``key_length``: The length of ``key`` or -1 to use strlen().
|
||||
* ``value``: true or false.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_bool()` function shall append a new element to ``bson`` containing the boolean provided.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the value grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_code
|
||||
|
||||
bson_append_code()
|
||||
==================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_CODE(b, key, val) \
|
||||
bson_append_code (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_code (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const char *javascript);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: The key name.
|
||||
* ``key_length``: The length of ``key`` or -1 to use strlen().
|
||||
* ``javascript``: A UTF-8 encoded string containing the javascript.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_code()` function shall append a new element to ``bson`` using the UTF-8 encoded ``javascript`` provided. ``javascript`` must be a NULL terminated C string.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``javascript`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,40 @@
|
||||
:man_page: bson_append_code_with_scope
|
||||
|
||||
bson_append_code_with_scope()
|
||||
=============================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_CODE_WITH_SCOPE(b, key, val, scope) \
|
||||
bson_append_code_with_scope (b, key, (int) strlen (key), val, scope)
|
||||
|
||||
bool
|
||||
bson_append_code_with_scope (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const char *javascript,
|
||||
const bson_t *scope);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``javascript``: A NULL-terminated UTF-8 encoded string containing the javascript fragment.
|
||||
* ``scope``: Optional :symbol:`bson_t` containing the scope for ``javascript``.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_code_with_scope()` function shall perform like :symbol:`bson_append_code()` except it allows providing a scope to the javascript function in the form of a bson document.
|
||||
|
||||
If ``scope`` is NULL, this function appends an element with BSON type "code", otherwise with BSON type "code with scope".
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``javascript`` and ``scope`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_date_time
|
||||
|
||||
bson_append_date_time()
|
||||
=======================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_DATE_TIME(b, key, val) \
|
||||
bson_append_date_time (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_date_time (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
int64_t value);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``value``: The date and time as specified in milliseconds since the UNIX epoch.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_date_time()` function shall append a new element to a ``bson`` document containing a date and time with no timezone information. ``value`` is assumed to be in UTC format of milliseconds since the UNIX epoch. ``value`` *MAY* be negative.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``value`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,40 @@
|
||||
:man_page: bson_append_dbpointer
|
||||
|
||||
bson_append_dbpointer()
|
||||
=======================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_DBPOINTER(b, key, coll, oid) \
|
||||
bson_append_dbpointer (b, key, (int) strlen (key), coll, oid)
|
||||
|
||||
bool
|
||||
bson_append_dbpointer (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const char *collection,
|
||||
const bson_oid_t *oid);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``collection``: The target collection name.
|
||||
* ``oid``: The target document identifier.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
.. warning::
|
||||
|
||||
The dbpointer field type is *DEPRECATED* and should only be used when interacting with legacy systems.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the array grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_decimal128
|
||||
|
||||
bson_append_decimal128()
|
||||
========================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_DECIMAL128(b, key, val) \
|
||||
bson_append_decimal128 (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_decimal128 (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const bson_decimal128_t *value);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``value``: A :symbol:`bson_decimal128_t`.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_decimal128()` function shall append a new element to ``bson`` containing a Decimal 128.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``value`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_document
|
||||
|
||||
bson_append_document()
|
||||
======================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_DOCUMENT(b, key, val) \
|
||||
bson_append_document (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_document (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const bson_t *value);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``value``: A :symbol:`bson_t` containing the sub-document to append.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_document()` function shall append ``child`` to ``bson`` using the specified key. The type of the field will be a document.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``value`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,38 @@
|
||||
:man_page: bson_append_document_begin
|
||||
|
||||
bson_append_document_begin()
|
||||
============================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_DOCUMENT_BEGIN(b, key, child) \
|
||||
bson_append_document_begin (b, key, (int) strlen (key), child)
|
||||
|
||||
bool
|
||||
bson_append_document_begin (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
bson_t *child);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``child``: An uninitialized :symbol:`bson_t` to be initialized as the sub-document.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_document_begin()` function shall begin appending a sub-document to ``bson``. Use ``child`` to add fields to the sub-document. When completed, call :symbol:`bson_append_document_end()` to complete the element.
|
||||
|
||||
``child`` *MUST* be an uninitialized :symbol:`bson_t` to avoid leaking memory.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if ``bson`` must grow larger than INT32_MAX.
|
@@ -0,0 +1,28 @@
|
||||
:man_page: bson_append_document_end
|
||||
|
||||
bson_append_document_end()
|
||||
==========================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
bool
|
||||
bson_append_document_end (bson_t *bson, bson_t *child);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``child``: The child :symbol:`bson_t` initialized in a call to :symbol:`bson_append_document_begin()`.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_document_end()` function shall complete the appending of a document with :symbol:`bson_append_document_begin()`. ``child`` is invalid after calling this function.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if successful.
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_double
|
||||
|
||||
bson_append_double()
|
||||
====================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_DOUBLE(b, key, val) \
|
||||
bson_append_double (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_double (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
double value);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``value``: A double value to append.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_double()` function shall append a new element to a bson document of type ``double``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``value`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_int32
|
||||
|
||||
bson_append_int32()
|
||||
===================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_INT32(b, key, val) \
|
||||
bson_append_int32 (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_int32 (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
int32_t value);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``value``: An int32_t.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_int32()` function shall append a new element to ``bson`` containing a 32-bit signed integer.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``value`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_int64
|
||||
|
||||
bson_append_int64()
|
||||
===================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_INT64(b, key, val) \
|
||||
bson_append_int64 (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_int64 (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
int64_t value);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``value``: An int64_t.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_int64()` function shall append a new element to ``bson`` containing a 64-bit signed integer.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``value`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,33 @@
|
||||
:man_page: bson_append_iter
|
||||
|
||||
bson_append_iter()
|
||||
==================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
bool
|
||||
bson_append_iter (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const bson_iter_t *iter);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: Optional field name. If NULL, uses :symbol:`bson_iter_key(iter) <bson_iter_key>`.
|
||||
* ``key_length``: The length of ``key`` or -1 to use strlen().
|
||||
* ``iter``: A :symbol:`bson_iter_t` located on the position of the element to append.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Appends the value at the current position of ``iter`` to the document.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if successful; ``false`` if the operation would overflow the maximum document size or another invalid state is detected.
|
@@ -0,0 +1,32 @@
|
||||
:man_page: bson_append_maxkey
|
||||
|
||||
bson_append_maxkey()
|
||||
====================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_MAXKEY(b, key) \
|
||||
bson_append_maxkey (b, key, (int) strlen (key))
|
||||
|
||||
bool
|
||||
bson_append_maxkey (bson_t *bson, const char *key, int key_length);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_maxkey()` function shall append an element of type BSON_TYPE_MAXKEY to a bson document. This is primarily used in queries and unlikely to be used when storing a document to MongoDB.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the value grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,32 @@
|
||||
:man_page: bson_append_minkey
|
||||
|
||||
bson_append_minkey()
|
||||
====================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_MINKEY(b, key) \
|
||||
bson_append_minkey (b, key, (int) strlen (key))
|
||||
|
||||
bool
|
||||
bson_append_minkey (bson_t *bson, const char *key, int key_length);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_minkey()` function shall append an element of type BSON_TYPE_MINKEY to a bson document. This is primarily used in queries and unlikely to be used when storing a document to MongoDB.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the value grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,31 @@
|
||||
:man_page: bson_append_now_utc
|
||||
|
||||
bson_append_now_utc()
|
||||
=====================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
bool
|
||||
bson_append_now_utc (bson_t *bson, const char *key, int key_length);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_now_utc()` function is a helper to get the current date and time in UTC and append it to ``bson`` as a BSON_TYPE_DATE_TIME element.
|
||||
|
||||
This function calls :symbol:`bson_append_date_time()` internally.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the value grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,31 @@
|
||||
:man_page: bson_append_null
|
||||
|
||||
bson_append_null()
|
||||
==================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_NULL(b, key) bson_append_null (b, key, (int) strlen (key))
|
||||
|
||||
bool
|
||||
bson_append_null (bson_t *bson, const char *key, int key_length);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_null()` function shall append a new element to ``bson`` of type BSON_TYPE_NULL.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the value grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,36 @@
|
||||
:man_page: bson_append_oid
|
||||
|
||||
bson_append_oid()
|
||||
=================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_OID(b, key, val) \
|
||||
bson_append_oid (b, key, (int) strlen (key), val)
|
||||
|
||||
bool
|
||||
bson_append_oid (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const bson_oid_t *oid);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``oid``: A bson_oid_t.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The :symbol:`bson_append_oid()` function shall append a new element to ``bson`` of type BSON_TYPE_OID. ``oid`` *MUST* be a pointer to a :symbol:`bson_oid_t`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending ``oid`` grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,47 @@
|
||||
:man_page: bson_append_regex
|
||||
|
||||
bson_append_regex()
|
||||
===================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_REGEX(b, key, val, opt) \
|
||||
bson_append_regex (b, key, (int) strlen (key), val, opt)
|
||||
|
||||
bool
|
||||
bson_append_regex (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const char *regex,
|
||||
const char *options);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``regex``: An ASCII string containing the regex.
|
||||
* ``options``: An optional string containing the regex options as a string.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Appends a new field to ``bson`` of type BSON_TYPE_REGEX. ``regex`` should be the regex string. ``options`` should contain the options for the regex.
|
||||
|
||||
Valid characters for ``options`` include:
|
||||
|
||||
* ``'i'`` for case-insensitive.
|
||||
* ``'m'`` for multiple matching.
|
||||
* ``'x'`` for verbose mode.
|
||||
* ``'l'`` to make \w and \W locale dependent.
|
||||
* ``'s'`` for dotall mode ('.' matches everything)
|
||||
* ``'u'`` to make \w and \W match unicode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the regex grows ``bson`` larger than INT32_MAX.
|
@@ -0,0 +1,47 @@
|
||||
:man_page: bson_append_regex_w_len
|
||||
|
||||
bson_append_regex_w_len()
|
||||
==========================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
bool
|
||||
bson_append_regex_w_len (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const char *regex,
|
||||
int regex_length,
|
||||
const char *options);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``regex``: An ASCII string containing the regex.
|
||||
* ``regex_length``: The length of ``regex`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``options``: An optional string containing the regex options as a string.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Appends a new field to ``bson`` of type BSON_TYPE_REGEX. ``regex`` should be the regex string. ``options`` should contain the options for the regex.
|
||||
|
||||
Valid characters for ``options`` include:
|
||||
|
||||
* ``'i'`` for case-insensitive.
|
||||
* ``'m'`` for multiple matching.
|
||||
* ``'x'`` for verbose mode.
|
||||
* ``'l'`` to make \w and \W locale dependent.
|
||||
* ``'s'`` for dotall mode ('.' matches everything)
|
||||
* ``'u'`` to make \w and \W match unicode.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the regex grows ``bson`` larger than INT32_MAX.
|
||||
|
@@ -0,0 +1,38 @@
|
||||
:man_page: bson_append_symbol
|
||||
|
||||
bson_append_symbol()
|
||||
====================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define BSON_APPEND_SYMBOL(b, key, val) \
|
||||
bson_append_symbol (b, key, (int) strlen (key), val, (int) strlen (val))
|
||||
|
||||
bool
|
||||
bson_append_symbol (bson_t *bson,
|
||||
const char *key,
|
||||
int key_length,
|
||||
const char *value,
|
||||
int length);
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
* ``bson``: A :symbol:`bson_t`.
|
||||
* ``key``: An ASCII C string containing the name of the field.
|
||||
* ``key_length``: The length of ``key`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
* ``value``: The symbol.
|
||||
* ``length``: A length of ``symbol`` in bytes, or -1 to determine the length with ``strlen()``.
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Appends a new field to ``bson`` of type BSON_TYPE_SYMBOL. This BSON type is deprecated and should not be used in new code.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
Returns ``true`` if the operation was applied successfully. The function will fail if appending the value grows ``bson`` larger than INT32_MAX.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user