From d65fdcc0df0cfe02aa60b934e601e0f86d389ceb Mon Sep 17 00:00:00 2001 From: jokingww Date: Mon, 12 Apr 2021 08:20:14 +0800 Subject: [PATCH] first commit --- SearchFramework1.0.1/.idea/.gitignore | 8 + SearchFramework1.0.1/.idea/misc.xml | 6 + SearchFramework1.0.1/.idea/modules.xml | 8 + SearchFramework1.0.1/.idea/uiDesigner.xml | 124 + SearchFramework1.0.1/SearchFramework1.0.1.iml | 32 + .../SearchFramework1.0.1/META-INF/MANIFEST.MF | 3 + .../SearchFramework1.0.1/algs4/util/In.class | Bin 0 -> 13513 bytes .../SearchFramework1.0.1/algs4/util/Out.class | Bin 0 -> 4364 bytes .../algs4/util/StdIn.class | Bin 0 -> 8811 bytes .../algs4/util/StdOut.class | Bin 0 -> 3421 bytes .../algs4/util/StdRandom.class | Bin 0 -> 9077 bytes .../algs4/util/Stopwatch.class | Bin 0 -> 1379 bytes .../algs4/util/StopwatchCPU.class | Bin 0 -> 1673 bytes .../core/problem/Action.class | Bin 0 -> 309 bytes .../core/problem/Problem.class | Bin 0 -> 3245 bytes .../core/problem/State.class | Bin 0 -> 454 bytes .../core/runner/EngineFeeder.class | Bin 0 -> 2420 bytes .../core/runner/HeuristicType.class | Bin 0 -> 1271 bytes .../core/runner/ProblemType.class | Bin 0 -> 1096 bytes .../core/runner/SearchRunner.class | Bin 0 -> 2012 bytes .../core/solver/Node.class | Bin 0 -> 4322 bytes .../core/solver/Searcher.class | Bin 0 -> 929 bytes .../solver/blinded/BreadthFirstSearch.class | Bin 0 -> 319 bytes .../solver/blinded/DepthFirstSearch.class | Bin 0 -> 313 bytes .../solver/heuristic/AbstractFrontier.class | Bin 0 -> 1638 bytes .../solver/heuristic/BestFirstSearch.class | Bin 0 -> 2447 bytes .../solver/heuristic/EvaluationType.class | Bin 0 -> 1097 bytes .../core/solver/heuristic/Predictor.class | Bin 0 -> 188 bytes .../g04/problem/npuzzle/MyFeeder.class | Bin 0 -> 2729 bytes .../g04/problem/npuzzle/Puzzle.class | Bin 0 -> 4407 bytes .../g04/problem/npuzzle/PuzzleAction.class | Bin 0 -> 1218 bytes .../g04/problem/npuzzle/PuzzleState.class | Bin 0 -> 6944 bytes .../g04/solver/heuristic/IDAStarSearch.class | Bin 0 -> 2381 bytes .../g04/solver/heuristic/MyFrontier$1.class | Bin 0 -> 1033 bytes .../g04/solver/heuristic/MyFrontier.class | Bin 0 -> 2949 bytes .../heuristic/VeryEffecientFrontier.class | Bin 0 -> 3204 bytes .../xu/problem/pathfinding/Direction.class | Bin 0 -> 2743 bytes .../xu/problem/pathfinding/FeederXu.class | Bin 0 -> 2912 bytes .../xu/problem/pathfinding/GridType.class | Bin 0 -> 1494 bytes .../xu/problem/pathfinding/Move.class | Bin 0 -> 1451 bytes .../xu/problem/pathfinding/PathFinding.class | Bin 0 -> 4854 bytes .../xu/problem/pathfinding/Point.class | Bin 0 -> 4115 bytes .../xu/problem/pathfinding/Position.class | Bin 0 -> 5030 bytes .../xu/solver/heuristic/LinkedFrontier.class | Bin 0 -> 2539 bytes .../jdk1.8.0_131/.idea/checkstyle-idea.xml | 16 + .../jdk1.8.0_131/.idea/dbnavigator.xml | 464 ++++ .../production/jdk1.8.0_131/.idea/misc.xml | 6 + .../production/jdk1.8.0_131/.idea/modules.xml | 8 + .../jdk1.8.0_131/.idea/workspace.xml | 64 + .../production/jdk1.8.0_131/jdk1.8.0_131.iml | 16 + .../jdk1.8.0_131/launcher/defines.h | 90 + .../jdk1.8.0_131/launcher/emessages.h | 107 + .../production/jdk1.8.0_131/launcher/java.c | 2081 +++++++++++++++++ .../production/jdk1.8.0_131/launcher/java.h | 309 +++ .../jdk1.8.0_131/launcher/java_md.c | 1521 ++++++++++++ .../jdk1.8.0_131/launcher/java_md.h | 57 + .../jdk1.8.0_131/launcher/jli_util.c | 121 + .../jdk1.8.0_131/launcher/jli_util.h | 105 + .../production/jdk1.8.0_131/launcher/main.c | 134 ++ .../jdk1.8.0_131/launcher/manifest_info.h | 187 ++ .../jdk1.8.0_131/launcher/parse_manifest.c | 698 ++++++ .../jdk1.8.0_131/launcher/splashscreen.h | 34 + .../launcher/splashscreen_stubs.c | 90 + .../jdk1.8.0_131/launcher/version_comp.c | 357 +++ .../jdk1.8.0_131/launcher/version_comp.h | 37 + .../jdk1.8.0_131/launcher/wildcard.c | 501 ++++ .../jdk1.8.0_131/launcher/wildcard.h | 31 + .../problem/pathfinding/PathFeederTest.class | Bin 0 -> 1271 bytes .../problem/pathfinding/PathFindingTest.class | Bin 0 -> 1569 bytes .../xu/problem/pathfinding/PositionTest.class | Bin 0 -> 1088 bytes .../solver/heuristic/LinkedFrontierTest.class | Bin 0 -> 2537 bytes .../resources/pathfinding.txt | 4 + SearchFramework1.0.1/src/META-INF/MANIFEST.MF | 3 + SearchFramework1.0.1/src/algs4/util/In.java | 819 +++++++ SearchFramework1.0.1/src/algs4/util/Out.java | 341 +++ .../src/algs4/util/StdIn.java | 696 ++++++ .../src/algs4/util/StdOut.java | 339 +++ .../src/algs4/util/StdRandom.java | 674 ++++++ .../src/algs4/util/Stopwatch.java | 110 + .../src/algs4/util/StopwatchCPU.java | 112 + .../src/core/problem/Action.java | 6 + .../src/core/problem/Problem.java | 143 ++ .../src/core/problem/State.java | 24 + .../src/core/runner/EngineFeeder.java | 85 + .../src/core/runner/HeuristicType.java | 16 + .../src/core/runner/ProblemType.java | 8 + .../src/core/runner/SearchRunner.java | 74 + .../src/core/solver/Node.java | 149 ++ .../src/core/solver/Searcher.java | 29 + .../solver/blinded/BreadthFirstSearch.java | 4 + .../core/solver/blinded/DepthFirstSearch.java | 4 + .../solver/heuristic/AbstractFrontier.java | 70 + .../solver/heuristic/BestFirstSearch.java | 77 + .../core/solver/heuristic/EvaluationType.java | 11 + .../src/core/solver/heuristic/Predictor.java | 18 + .../src/g04/problem/npuzzle/MyFeeder.java | 84 + .../src/g04/problem/npuzzle/Puzzle.java | 155 ++ .../src/g04/problem/npuzzle/PuzzleAction.java | 40 + .../src/g04/problem/npuzzle/PuzzleState.java | 252 ++ .../g04/solver/heuristic/IDAStarSearch.java | 65 + .../src/g04/solver/heuristic/MyFrontier.java | 125 + .../heuristic/VeryEffecientFrontier.java | 147 ++ .../src/xu/problem/pathfinding/Direction.java | 60 + .../src/xu/problem/pathfinding/FeederXu.java | 109 + .../src/xu/problem/pathfinding/GridType.java | 23 + .../src/xu/problem/pathfinding/Move.java | 43 + .../xu/problem/pathfinding/PathFinding.java | 146 ++ .../src/xu/problem/pathfinding/Point.java | 107 + .../src/xu/problem/pathfinding/Position.java | 132 ++ .../xu/solver/heuristic/LinkedFrontier.java | 89 + .../problem/pathfinding/PathFeederTest.java | 29 + .../problem/pathfinding/PathFindingTest.java | 28 + .../xu/problem/pathfinding/PositionTest.java | 20 + .../solver/heuristic/LinkedFrontierTest.java | 65 + 114 files changed, 12750 insertions(+) create mode 100644 SearchFramework1.0.1/.idea/.gitignore create mode 100644 SearchFramework1.0.1/.idea/misc.xml create mode 100644 SearchFramework1.0.1/.idea/modules.xml create mode 100644 SearchFramework1.0.1/.idea/uiDesigner.xml create mode 100644 SearchFramework1.0.1/SearchFramework1.0.1.iml create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/META-INF/MANIFEST.MF create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/In.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/Out.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdIn.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdOut.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdRandom.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/Stopwatch.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StopwatchCPU.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/problem/Action.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/problem/Problem.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/problem/State.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/runner/EngineFeeder.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/runner/HeuristicType.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/runner/ProblemType.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/runner/SearchRunner.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/Node.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/Searcher.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/blinded/BreadthFirstSearch.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/blinded/DepthFirstSearch.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/AbstractFrontier.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/BestFirstSearch.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/EvaluationType.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/Predictor.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/MyFeeder.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/Puzzle.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/PuzzleAction.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/PuzzleState.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/IDAStarSearch.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/MyFrontier$1.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/MyFrontier.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/VeryEffecientFrontier.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/Direction.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/FeederXu.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/GridType.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/Move.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/PathFinding.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/Point.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/Position.class create mode 100644 SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontier.class create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/checkstyle-idea.xml create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/dbnavigator.xml create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/misc.xml create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/modules.xml create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/workspace.xml create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/jdk1.8.0_131.iml create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/defines.h create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/emessages.h create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java.c create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java.h create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java_md.c create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java_md.h create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/jli_util.c create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/jli_util.h create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/main.c create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/manifest_info.h create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/parse_manifest.c create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/splashscreen.h create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/splashscreen_stubs.c create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/version_comp.c create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/version_comp.h create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/wildcard.c create mode 100644 SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/wildcard.h create mode 100644 SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFeederTest.class create mode 100644 SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFindingTest.class create mode 100644 SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PositionTest.class create mode 100644 SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontierTest.class create mode 100644 SearchFramework1.0.1/resources/pathfinding.txt create mode 100644 SearchFramework1.0.1/src/META-INF/MANIFEST.MF create mode 100644 SearchFramework1.0.1/src/algs4/util/In.java create mode 100644 SearchFramework1.0.1/src/algs4/util/Out.java create mode 100644 SearchFramework1.0.1/src/algs4/util/StdIn.java create mode 100644 SearchFramework1.0.1/src/algs4/util/StdOut.java create mode 100644 SearchFramework1.0.1/src/algs4/util/StdRandom.java create mode 100644 SearchFramework1.0.1/src/algs4/util/Stopwatch.java create mode 100644 SearchFramework1.0.1/src/algs4/util/StopwatchCPU.java create mode 100644 SearchFramework1.0.1/src/core/problem/Action.java create mode 100644 SearchFramework1.0.1/src/core/problem/Problem.java create mode 100644 SearchFramework1.0.1/src/core/problem/State.java create mode 100644 SearchFramework1.0.1/src/core/runner/EngineFeeder.java create mode 100644 SearchFramework1.0.1/src/core/runner/HeuristicType.java create mode 100644 SearchFramework1.0.1/src/core/runner/ProblemType.java create mode 100644 SearchFramework1.0.1/src/core/runner/SearchRunner.java create mode 100644 SearchFramework1.0.1/src/core/solver/Node.java create mode 100644 SearchFramework1.0.1/src/core/solver/Searcher.java create mode 100644 SearchFramework1.0.1/src/core/solver/blinded/BreadthFirstSearch.java create mode 100644 SearchFramework1.0.1/src/core/solver/blinded/DepthFirstSearch.java create mode 100644 SearchFramework1.0.1/src/core/solver/heuristic/AbstractFrontier.java create mode 100644 SearchFramework1.0.1/src/core/solver/heuristic/BestFirstSearch.java create mode 100644 SearchFramework1.0.1/src/core/solver/heuristic/EvaluationType.java create mode 100644 SearchFramework1.0.1/src/core/solver/heuristic/Predictor.java create mode 100644 SearchFramework1.0.1/src/g04/problem/npuzzle/MyFeeder.java create mode 100644 SearchFramework1.0.1/src/g04/problem/npuzzle/Puzzle.java create mode 100644 SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleAction.java create mode 100644 SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleState.java create mode 100644 SearchFramework1.0.1/src/g04/solver/heuristic/IDAStarSearch.java create mode 100644 SearchFramework1.0.1/src/g04/solver/heuristic/MyFrontier.java create mode 100644 SearchFramework1.0.1/src/g04/solver/heuristic/VeryEffecientFrontier.java create mode 100644 SearchFramework1.0.1/src/xu/problem/pathfinding/Direction.java create mode 100644 SearchFramework1.0.1/src/xu/problem/pathfinding/FeederXu.java create mode 100644 SearchFramework1.0.1/src/xu/problem/pathfinding/GridType.java create mode 100644 SearchFramework1.0.1/src/xu/problem/pathfinding/Move.java create mode 100644 SearchFramework1.0.1/src/xu/problem/pathfinding/PathFinding.java create mode 100644 SearchFramework1.0.1/src/xu/problem/pathfinding/Point.java create mode 100644 SearchFramework1.0.1/src/xu/problem/pathfinding/Position.java create mode 100644 SearchFramework1.0.1/src/xu/solver/heuristic/LinkedFrontier.java create mode 100644 SearchFramework1.0.1/test/xu/problem/pathfinding/PathFeederTest.java create mode 100644 SearchFramework1.0.1/test/xu/problem/pathfinding/PathFindingTest.java create mode 100644 SearchFramework1.0.1/test/xu/problem/pathfinding/PositionTest.java create mode 100644 SearchFramework1.0.1/test/xu/solver/heuristic/LinkedFrontierTest.java diff --git a/SearchFramework1.0.1/.idea/.gitignore b/SearchFramework1.0.1/.idea/.gitignore new file mode 100644 index 0000000..5ade2d4 --- /dev/null +++ b/SearchFramework1.0.1/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/../../../../../../../:\Study\2021春\人工智能\SearchFramework1.0.2\SearchFramework1.0.1\.idea/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/SearchFramework1.0.1/.idea/misc.xml b/SearchFramework1.0.1/.idea/misc.xml new file mode 100644 index 0000000..c14dbda --- /dev/null +++ b/SearchFramework1.0.1/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/.idea/modules.xml b/SearchFramework1.0.1/.idea/modules.xml new file mode 100644 index 0000000..06a8e60 --- /dev/null +++ b/SearchFramework1.0.1/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/.idea/uiDesigner.xml b/SearchFramework1.0.1/.idea/uiDesigner.xml new file mode 100644 index 0000000..b93ac08 --- /dev/null +++ b/SearchFramework1.0.1/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/SearchFramework1.0.1.iml b/SearchFramework1.0.1/SearchFramework1.0.1.iml new file mode 100644 index 0000000..5165f39 --- /dev/null +++ b/SearchFramework1.0.1/SearchFramework1.0.1.iml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/META-INF/MANIFEST.MF b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/META-INF/MANIFEST.MF new file mode 100644 index 0000000..8b6e977 --- /dev/null +++ b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: runner.SearchRunner + diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/In.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/In.class new file mode 100644 index 0000000000000000000000000000000000000000..3363cd013549c22ff2881533f798bfb02089098a GIT binary patch literal 13513 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
DVmO8^x&7g_&3wj;1 z{t_c4yR^Uj3Qxj!o}>eYhc5Er1AZlet0Y)o!X!fQBq-7bYWI0<9`7cfusC}UwJ+8* zzMny(-sRLul%xFQRYl}e6QNZR6{$%n`b;p8q;Ha=V-8KA-)j22G@5=#Z#eV~A@w1d z;LSt72X%$e?M-^CKMnJHYq)+%KN^-o!!l@C4h>I+hUL(3*2mKD4}CTKqoW~yqtl;; zp57V;m-VAz1vIRLhI64|6*Qa+4bT2q8ot|C!}lBw@!Kay!_#rkNct~HSBsEfApc)T z9#yBO6~~dp+O87i(VytgSOMZGr{gYd=3dHe!fEQ#E((d0W*i>WiVPVh{RK%5(O>aH z^f&y-0pstu=g~jtpZ!bi=q+{K0Hywm{;z+jZM~&N1}ODUSSvOIlY}e$%NGW^DeMry z>C=*mA=TLUDTPZ z+kL{>7Lo6EQ4|fn814cVrH@N-zUf4SLI{p-r~C%I;p`X3t&0-4CWUM`wh&0zxQ%?c z1soAkgy>@l+%!;u%RWM&Z*wnHzRLvGz%}w+-dn&GA5*}Uy#-v=Q@|&yz~uNY`cyxh z*i`#I-CNAnJ;i(!wZ6~v7Vz2r1=tquW1)u-Bqr;ku8BhJ^{D2VIKLmp9%Rx7Jch^P z1YW_baSk&13j7J%9k?Il-|?GdDz}=UO3_c}72HNm@WtE6rS7D0>MokB?!kt9FP)+8 zqdDqZ*p#=^Jas=UR68i39-yFlkfLfQZB`G_RcaSqqjuBvs+(?9kI)v?MYpOwv{mh; zU1}dasve_*YCk=r4$zD0ar&|P0UcIP(J#~!^tyVI-cV1|+v-{Rt9p(;P%p4sy~z3M zB`#1e^GJ1w$EY9kc=akzP_OY6^%E{pKj%}_FStVel55qkxL*C5m#W|J1?soFTD{2^ zsW*77`aQR)w>YHU=D2!?uTbytwd#GoN&Sg$QGe#G>M#5a^$)&7{f+Nbf9LJ$pZtLO z7w=Xd@Lu&FKB)f7&#MplRdtjPBj*0v#r!*04!`Mg@mnr8zwgTBzq`DA#Fekyu0d+B zYp@#b8luLy3RID6sG98ZsTr;js?=4e%3Qy8;=-(Nj+&KIwLj7@cIq9RNoR}_Cj$lcF{G-I^%9SWfxt$o4mg3_R#ga(K<)pOMRcy_lk5Pq3dsm2L-6rkDwZ4dJAxl UI8W!EsBD_&AOm43yeM}6Kj~=N_5c6? literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/Out.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/Out.class new file mode 100644 index 0000000000000000000000000000000000000000..6c1dda194f43fa9b10fad45054520ef72eb1ccdc GIT binary patch literal 4364 zcmbW3OLQC68OQ%uQarMdAJ|FiBrbMB9LthpCt%VLr-1FmAwjkQIW|sE=|qej#j@l| zBM7gy&_W+jD32EU;JJX)?g$_s$bn_cVFfH{m(XR~C3MmD|J@mn$Ev2Mr<-r?-22_% z_qgAEeDu%vJ^(O+*J4Ov*+9X-N)*KyLMRznjiCwOX+{`j1CVK<|Sdt&UlH-<@E zG;m)Gt+-zl9}w}Nh=)XcSH$;3d|$-FA|4U(0}($I@u-N$MEpp^k45}M#7{*$E{30w z*3ZP?auiR>m+&wih~g>v-XF!!oAETBG4QNHeB$P@+cU>!@0uQ)IzF^*C4j0Vg z(s0Hu=Zj0D3M~_*V#PL#_MBO$S_)0+nTfIVhIZA?7lzZNoLR7_9WGUEg>4QfUmCuZ z6nnm$x2-Zqn~vs-dHV*19SKikrfRQNZJM*pmC=DYg~&wdZrW)}=Zn^Kb>*B@o;A-E z*wdk{%$eo9{JWjuQsrKS?uIzeuHx(spH9vkznHUD?R=?7pCb18d_|!>Z5Ea)Bf~lz z`oxh?iT&Ffk~!LvvCZ7_l)0)MG4LFNPl*3p-PnqjJ)9}!mMvR{)l|`Kg)1GRZ`i;u z=$|{ypMAka7xM+HXs%cWeyOk}S145&jj<|;EfnkK&78YngJ?0PwM7LX`a%}Q_>vQ&2jpp{ou;#@1jDYK^SM9h;?K>51STC zHDQ4a$zF-$S}+Sc^}b=b`-|DBK84oJg~gnmo}Ju(Sf)Nt!|PLh zJ4J?Gh~prx@s0bcHjZCm+`z9zzZgE6fS~DVU z6Oj>dTEx7Fg*aXky)3Ag6}_zJWkoM5dRfuSirz2|#PKb>%xuqE6}$H!^JB9yWMAak zI(^p|cqNWkaey05`{=6$?wEDA{Vwwa(A^vRWYb({jTBODdDJC;^gl~PmU(?|QrkTo z^j>Jw)vGu3Y}w3lg?(OT?yK0=ivIx7OGO9d#G;!^mc7~WuEc<2zTPRW{bHe7Ij=DN ze^<3f_7x1ha2)n+5}seDGuX{DKgAm>jGY+7ekcs_FN6sHxp2D8I^%a2$5=^}*YWRl zY~dWBFS!PF8KH$#M`R6KrjnP@v@pn~@eZPIAUZWzL+njXil7@kyzs&}#A#Q-pd4cF z0kpA7y9w(piEjWzp=}<5Kj$o868pTn3lV54wfE!7_iS15={zXX0 zK-j<-l!4}m_Icd(`4A^7Dn^r+aK#$pZ?YZI?#T5FLJeZYbllN%%}Cr6F5_Ls9ic{2 z;!f4jG9|$e>fon!@cSDEznfvL2fqhV5{{8G$-WcVikrC(X=na9#Y}5+ZwXn zQS{<%=7LY_FnHoN!tJV|vmW;#aSsLJZgp|D1>m;U;~pjMu|VAIE-vHY!g~AbVEb#> zR*!pKeA!x7Yw)pJ^>Y7#p8b)B@`pa}+PyMv_sW~(T#r^dF^5-OfLGoV$$xfZ~J>-#{rPpNE`Beerzmohn zlK&n^c1oU)tVU$!xhH`9CCOir{EtAgQ~i9od1PNUSpB_?$tr}X3ZqR$0?E!s$nsin z-VmFrF4$)kC%J{>)%DIMeG$hY~PGP48_x~3&eYisHLx<|uX5?`r_w@QhrjvKn z0Yaru49ZQ?sSSpC*;-h14OZx$jP+kecwr4!r&Aq!Yv|*Bvrl?D`qz+P-+p1TnH$B=(z_^6uTi7iI Rlzu}s>484VJo`ep@NX8;%7Op@ literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdIn.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdIn.class new file mode 100644 index 0000000000000000000000000000000000000000..7dc8f8b702ddbf70e4de568735804924dc6780de GIT binary patch literal 8811 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 bdX60i&%Rrgny=6<2LAMC@%k|) literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdOut.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdOut.class new file mode 100644 index 0000000000000000000000000000000000000000..bd9640083d8090af8ac804940989949d5c9131c7 GIT binary patch literal 3421 zcmbW4TXYju6o&tkrkOOPr5C7D1zTF67oea}F6CCzR!T|>q!-IY7}B%^(xfI6D2fW+ z!OH_a>Z2|nm9kdaCClrZ_^3XrkLsiP=wU@!GJtwKDdv=z(_(ZnXT(IsjEjkhnGiE6=B${wm~&#zi%E!?5@=Fd zDLzjX$5R^8zP(@eHQnHE02vtaAzOwExTs-9!=*Ajjb}7m_T$+A8t|N; zp4V_CfU7vA5DXpYIvVL2IyKOBs7Il?|D1k7Z%^pS$@YkmjwdHO70N@YWX8~w#)zKC z#uR-0gQ2eef_K)4C))c{Q9Ti(cS$O1C@i-?@l^X^QjF1b+=!+5)we62j2nCC*4#3p z;0>k5NnF|=PsRqaQ)go7A^l8(J=G>}L{G=%-R|@nXX6=#ntnYonc32A#*G-`gIR-Q zZCU~)l8oK#$YSu!xmeWblwfLRaf0?I&Z7C4`TdwQLuNB1&2F>VEzMrD*(=RHv)L!j zgJ$!fG$Up+BF+6~bH75VIVC1-J|`5KoinrRd%XB$eG{qll+H?e_4K49UBpjerww#2 zfrIxSArj`AF~pP}XWeR>oiXgOlFOpld0F^(MHBX7Dz4bt{E81JGui3sRN9D*_avjK zajK|iCK{VI;;E#_DPri+^M~|ldsPFGR5l%r^~Po0mssn$QDhjzCTtF3Bie)5CarDQ zE~Zn=ZZUhsbcqRx=?UTm@e7MzSp34`7Z$&;_=UwUEPm^;A&7pw$mEA&8J4+p&Bl(2 zfI?+q16cad@KO*j;}vl~q~X;dUc&~~#PnONZ-u&rUTShWYp_-^eaaHQhHH|`b%mrHrF%o_?#3#fl9r-nB~w^4sB>At+dgK@ z-Mn~#EH*atbgbi%T|(P}RxlRdJZR!OCBb$;^v353_ELWIc$9DLd@4RmTj!u|vf;sF zv_7+Qgf{>Xv>dP%9egXJ92W*RnqL5I7M>hRWVkYi2Z#Yq5OdNTu$}!9t%Lm%&Cda? zId}^Jtr0P3m~aI3V+VH9UxIcPVbtYN>SiR#NVyohY{u^544<2Ek&GD^V~@?)n`e}m zSxPQzbI{z3D`Z@CG4|Pvt~{eqkJUN&-HdBwTz4_{+l){V2J2DgX51j-Z5N~4X7uD4 zg&;aqt|9Uo@W$tDK?My$avqyIAAmS?vwE$86UYA2Tex!9->?#sW?TM zqbTPnC?2JD(0#TjD=bk4O);C}ti4ddO$B_$(4V6mUpT^7gDsOt*n~I1KxQ&SiQpg z3F^j5mf@j!tc=WKRpC^sMJadnR+Op^2Hu7WwH@_phoe*t3^dGuevIT#hRb%KmRUS< z3pKYB==$+-+^A*0rnr| mm&5$u;|Q9W&%#~VKvj+63HpukPlM;QhIJZI$N1{O@qYk^5jC#> literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdRandom.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/StdRandom.class new file mode 100644 index 0000000000000000000000000000000000000000..feb9cc720ec06a35044bc8292a7980cd41db2e76 GIT binary patch literal 9077 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 XGfu(=1%idMZ<+j*`#)5v;U|9s2OW*Z literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/Stopwatch.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/algs4/util/Stopwatch.class new file mode 100644 index 0000000000000000000000000000000000000000..5f903931f569c62c06065de5fd1397f66115772b GIT binary patch literal 1379 zcmZuxO>Y}j6g@99b=&UBQRWcedj@^x$6X5_O3_ISh-cVy=^;irQLU` z(SaKZjF)Y%5#GpmBG=2;qE`FJj_L=C0z-~xw?k)d%WV>Z6^cCl))DJ8ZP#aJ=F{?_ z{m9OHw%=fC;QEb4*@tlX+hCj>G+5!nIbjSSLLwq|aGjB1r%54LLX$q~y}Ls1jw1F` zzEX?q`sWq99X~_I6#=u>>I8LX)s=5ezIel&Y|cUoX&rYhtl*x7FAcN4D2-s{0bNm_38q3n2BQFAZj|+96(|O@1RLWzK2j zEW^Et#EYP`<+^B@B3r>5+-{4j%$Z6Ws43LR4$pB~OR)`Dxn~f$E(U&v@+18NxX3ff zTi|V|n8gq>n4o1bQ=XHUq7;&_KGr(pWc&zWmM`aig5o?$L2dm&Uk}fu1V2g@g&1o* zwnzF{Dp6l!j{<{u9hZBk;uwke1y6HIq05i&H|RUhU{sPNbzVzrm%hVTHmyDGVz6F1 z*2MQG|6KhA=7Kghr2P(SN6B`%y*uiJCS@1Ne*P^zxnQXCX4)je#R(&AK2Bk{%T-x0 zj!nY+J*i6^^Eu9h(FZd7KypknY)R*tUSf|8Y#}vXRy)~-l1mVDv_>1Jz+6T$2FltS4ir=NS*M`cd(Lydo;UgZpPzpNFpW=j z1TmxIUA)%~KW2My6LV6V*YLi7;pIzJEOU3GRIwa^ z%jpC2v6(2Fb}>;gZL?@qEZa?Ncs`j2i9;XuiamxMhicJ+{{DrU)Mx6y|kMdw|oWEbaTDWb$L$Kf-bB9mM=$Bhm| z@Vm14>-4NQDio?bQ?~3=Ejxv0r|iwUX5q7pS@XKk5Esz%)rM2BmP@kLP-hF1a-aq- z;uQ_620lRAzz~KtWDI1HGcbZtfua8yfQB^#_pz=aZ(swP242Ty4s*g9i%v{V?Tyu~ zLe<`_$8>@Iv(@Ex4y=N!VavdWc%Wh1z(;s!;A4CuaOKReW5t=%Z7-Vzx9WVsB^E8W zbMpcd(OAcW z49yT$yU3d;S;rw_iZd1Xq1CYDB&G4B=QrebPivVf9EA-yZ*U^+y=9 zYPeVZ6~S#K)dotlm*B3*;;n8{QP?+6Wkh1~cX1INS+oS2kT`v?(FyMs^gj7{RLW*Djb$46~T%~d4xbR&}NDO=cAB8xl zjCiM=Wu`UBY2MHTng&0zBgY literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/problem/Problem.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/problem/Problem.class new file mode 100644 index 0000000000000000000000000000000000000000..b332891db3f487b0f57516b4a574693c2bc69611 GIT binary patch literal 3245 zcmb_eT~iZh6n-{en}ihv0gaZ5wJngK(W^#Qkan!GmW#DZ$beJO*jWjmK!=2#dJx|Y|*+Y zueZdgC@ya6DCuxC7OPm8<{kc^-UAuw6j2jmT|jeO;m5sTka*3o;0+LI|Z{iZMwF+2f~=QWLGqF zhS4Vd;22i_EBhW3=PiqtHx^2_v$rpdy`Hd6)pIIm*-fdmqrH7hT(7LZ$9jEK3c{#6 z8-^tjh_MfwtT@HHe(J=%!pgXg<7qe+*vhfx=9jFhYgatGke_s|1-sxm?obeNpfSOM zvJ|QE`niUEeop@ap&?yZvWp91%mR;vohr!x#ONEpY2G#SMYFV+AM-3%l3^h6iqE8E z+4Po9I~C@Xu4O@AaphPpTrn-2MZzq2wo}s35x$m_N=)=b*>tTEG2<&YNY$P90?(cUbr-d$DAC zRhJ~b`hV4NIM+CYWW}?}eo~oU`x=BoVH8eBzeU6r<|%=u+G{tER0|T925o` zcoS0wGT3ckk1TIuuYotvrD6MKis^6-45A`RB+(AV;PB-esG`TfT`cRkXW%{_82Ac@ z4LrmnT7<@%9=pKm{!0g24;X z{N9S13k#e<0c}-~0j^By1c_}HE3tk2qVD2XJBpaFkGq%2=;MpBLL9OwS(X3PBhcOTat91G+w~Oj4Ij-4Yd8N9>_HQ|MDVl9uTjHS%|tX}sDvVFCn-fKeHT4} zr#zpc70>>H$WPq(X(W_zuYxvwg#enPprLVev+@3h#(j*`FJ-;w_>Y@B_cS!lp+7Jl zVVsguBD*J4nzWMU5T~Y;rPJ4{l_eoVg%}zR;NTW4xzCL<`&fBm9eN3tFh;QQjj`%z z;bR>k*3p+>2??~AMqh^+cPrk*ks!WV5=nCHdXB`bT$83nbMoXb`V4v$Ye;TX-)F}t zIe3Q2j@G&Bs+FOOVH_iTD+cgB!Mg!%20GaUtUO0*b`9x?+$x#|W0}}0jAz)UVKAPF zKSQ&ICzz96i-zB^eK3*D#4?Fhv_8Qpf7dps({@KTql>)#`arTjqt}8RNJ$lU_x~%nyHme?St6sa86u!kI)87uiOaSea=I;WAUYf+@_w#8p&q4G*|` zgn5^Na`4EPwcZfs&I7Zk;OuAN@6@0`~X^9n8 zqzJ8-aRMjVIL)|&Q$&v8G|#0k{IgM>ouQ;1(HGdQBc{SObfzkvV% literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/problem/State.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/problem/State.class new file mode 100644 index 0000000000000000000000000000000000000000..7dc90c065006d33da5ec1525f21b77fca6fece36 GIT binary patch literal 454 zcmZut%SyvQ6g|`C(Z*1UgrJK^_mgy}Q__r#lj?7|5?uHJew26< zD-v`T_uR)h_c0%zZ|?xkapIwkp^IY|BL-(C3u)#I?I2t*SeI%k7<#cR#7((Lg}&oy zPMJZhGM+EEmQ}n@IM- zubw)orueX6)3tvOV(9;_ahtA1W~@`R=r5~hfewXD)}bgOWQ6wFE7%J;Ex2TzI@v*o feE*w(E<92*?2))aANw^Ppht{;tvw`fPdvAeCDL9UyfmihXb$lG89S%w)|>Q2OK# z@h)Yd^%s&@Ok&AEV$OE$aNa;yZfx5?e95aw1AV6L%8mNruJpIW zu0u(`>6L}EEqq(?4PiXovjYQzX4&&)!LPfn^b0F)mBvLWE7G4eaIGrClJC*zkg5-J zrf{mkOrajyPGQZR9W(dEk%-s@-xtTG9fUONvFxfV!n)7c^H(yOi%`^}ScOK+*?Bt4 z=USpzWub6h7iJ4Q=TgDCHt-f#)2tLVL3AGfTT%SUD0-U4*vhZXMSo zA?ZS%Q(M>#LSK|mJu;$xppL$ z6n=S6w=+vUONDC645TPphzzH%4x?$$*zu6b8@PQ*3XJmdw44`JvqPCu^5>dEv=uee zXOm`0HDd$qGffbUxgKp-eXGw*HI#a;RF{|S{R7n<1MfNFaJM2xT7)B02F4q3n}Zpd zN4d7k#?}mU2g*C0by8rds-AGzEz7I>Wm&YuB0JCEC<48o%A2VvBsB)-aE6?c@^wG6&S(Li?5^Foz&ZC!?YUM1*D;F~Na zNz4q^vB4o~9mrOQwANT0;Z_TqyZf?CC?lPrv@ZzrFFrR-o{^|J=N6@1oh=@&PR$gW zRd#FjSFapdC~2bmz(Z4OZh?UpZL7~2xggBBLAyZjY{ArR?I|s6t^T;QX>FykiITd~ z&)CY-YrymP;H||weaCaw+|?w$&A`HU8BAc(!2PpY+U}8eAPc4*L-s|yV;|>&5S}T^W8kfiw)YUwrnF zE07wb-T4z3zw=KFSw0h5IEd@~pNSOEk9UDMcN_0hGN5&DX#VCYe~Uc#RqK6#JDLt* zSkt?TQu7|}^QnUWf^L4}fuZ~#i2aGK^*4y`oS=K-4H7$(6XSm&d4kk$)acTvdP#vr zq_9lBsL|yk4-q=$3lA_t|0yCI#Y3G>FCHOB+cCaZ*<_jiBjhRJeIu#}%}+$5{0|dN z57C$nG(?rynHYb~%Ao_CO@?|#mzIWeH*(Q{lfn%RLWS(pAYv^blq8Q>Hmz2n0pba1 zj38oNzp5wgn$3v(4@7VAn4MF<7^ZX&yYQjrKEgJs>hTu7$8+4m7vxpa^F;O(U*hTi D6?Trq literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/runner/HeuristicType.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/runner/HeuristicType.class new file mode 100644 index 0000000000000000000000000000000000000000..859113e18bf3280e883b3f9df5861ca8c30076db GIT binary patch literal 1271 zcmaJ>e^U}s6g>|Xc3Iaz{0X9&X@aI?X<3j-h)ILsxaiDI%{VJ2j?5D?Sv8%*q~36C=P;G%x_!7%tC-b2)3tf6c0tK8 zkEw3>?_v!8wC&i9RfeH|?3GXKF-VO!HuV$G?L)_GG+nCXjq`+(u2kDE&v%s0InCpA z7n7@WKB``8x)p1~=KY4RoZbTOSi^OGdnPnw@RT9)-?P>*jjV=Q%xM_Lh=vFcQ65Hl zi19GS!#GA5u3e6k+hp)nsx^l^48#*1EtC$9tV)A?E_V(kTQ%$TREO-(iCnFkT3e(m zJ4C++Wi7&80fb~sAbAr=_5_kcfn-u3`2<2yJ^-p9A%Gj01j9{Y9QmWRz&^oq4(|tI z3{w>SBIhOjG;X!^OYn$QH7w13hVL8_*L$w$XJ|#cP$70VCrGa#*ZhJ6 z1qsQ5^a&DH1nC!KAatP{49VZ9y0=AF)sR}~(G6bzzxr#4NY& z+pTs$OyM*SD21BWJ)G^K-tgOv!j%$NssF0gYzH-G)8(}$dSLb{cZha*8JKM-Ms`|;KR`aCMmmUF)o2Gp)(IHbbl!q-MCe^Yoa_`eWDfM7ll)Lu L(;U(i4cF)Q#Oflqa` zVNT#P9UYj}F@=ZfF)#2)M-~fRn8xSo@r6K6;7c7n3f76oI=YeX#3Giu@C3^`zQT%< z7Sz{j0$;25n!q;#-)e}@*p3~{YG}_4uW5)qbW2i0Z{Bv~QhjGrdaKrEl{?A2TePZc zmS?MVb2AoHY+u9We9`r!>D3)adS*ddUa_(gE~aU5$Fdy_sm#;-wzX@SRm&-xg}}3& z^0e~U=?89Y&kBkag7Q|i>`$8Yz^)S0+*d|wRzP`QWFi#L%jb1Tk*Ikt8SNA3lP30jniRg9?u*YBty*}#0wV(J0viHPHRuJm?iJ;Nt*W7~ z^^nKaxf*yIS7_l(_B5nD>4$p0sg7{Vc1k?>@!&%s?3x12(n=o*AfON5C=Qq9*X% zfCt||fV%qH)i8VifBlpd20!#~eWT&hX|p`p+?GX_<{5Nr`LVP^bl4Xs=ggix-OUBk zvjUg3H<*cv;(Q-=m1VFTwG38^6`d@w71fin~{Et4x*4 zsWi|`M$1G|GpQx{g?&Fz!=>F-)1legw#(^aI|0X-w06j)_cWf+6S@2L0UL#Z z8H%s+84ovm@GifN2!Qu!1iT-v<9+T>S=&H6*TBIM+SZfphlu5m(6N4q_~PhD17c~k zfy8TcW@BRw=-G~R$18Mc_!*DYm!aV`y0h^k^iZWYE7Gxayn##EL^_^MG|=}elIg@N z^lNBfKrKWAgAJtknS85(pA!%_iBqFXw?ZiY*u%UsBrHMU>G$W*u ziD?6ELLe=r3#FxWU+Lzy5U>qSOT*Wm{)+yPo<8@^NE*pXPEY$mGk4zmF3-E(tAG4^ z^CJNJ@o@|hJQKq(&P2J=#bZG{^5Rht4@1S-7#6VU0gOQ>0@?5?&^8Rv@HewtCX7rxN!K8X_?Nrg7KkNpWKMFn3Q6zT%PB{rxXM;43dIvQ>JActCbdv z%B;@Vics2ly?9EmnBv(kZ^dghdKjhXBI+0K$tQ4p{f&WVJ|>h-fJxQ%e~=UK@01Q#m$bCej8IcgMtv(P+*&A7GI z@o>jNX2}K}mbrq#n}okjje-+iQT%TPJ9Z8esPc(c6`!)O&KO@-Y;Au_=7G=8w zM`~;;k#glJ4L`>(G(3r?82f*%Ug4{2B*E049!ZG3Uy|vxf;*a;y^*G1w;%k?GA$zT zD-FNK9KAha+fLP~=;dj{S+Wb&ZDIVT2XAi+;kP~bord4z4;uc6RSkc_pEdjibKH7I z!@F{EjT)MsxFyVb-8$;&iDg{im`-(`7;P0_f5AWZ^gRHn{tjSG(I^+l!Lp4Uc#g)U=tT^a**Sl99#%F7mJj>IwHg_kyFGAJw z@+@V;OQ{DvXtxr&=>Q9qMbZxVy%Qbdo!tJh>W@w%+|ilCvy;zcj^}2DpX;0`lSfaU z$mV9V89~@k@qva9@iz@eF`?lL;xUB@1@|>u!?c#|^G13~FD(>wwwiuc7YE^rg6>lD zOU2)r-6`8XUn?^NS<5miG7ko8_n&_Jo<6r}Cv~e(G^)E@LBCsGP56qaMbLMDkx}^X zH(ir{Q(I;I!Sr@Bda;-@dGk|oL&2Uc@#*A`f}OYK!#-wVnD@~zucMsnT*bv`mv2sY z`R0I^Z_aqW?-mo9x77!@?!p1w&h)kC0$M&lJ>;DK%huYfkAM`#2JHtwDFK<;|=bFxtB<8pevbLLm)Y_hG24Z4WVRz za1G&Pe`pPA)ACNJoNyvx@GzkxlSc#|z zPZQ$oLkPSr;9)*R6rQIQu{U@fk@@8N2&C2#O{TaCa}_%?B50!@qB{Ua=pAx)K}0An zr4A6=LEOuj?qPhJks54Z8pv4@a7B!4;ytP}59U5+9bT zHJ8Ctt%yD(ML4maYK3r2z~)aqv&t_QsH-9C(-3QD;L+}B@S6{`o1gXxhZ@3JJk~)t z*e?8dM`4bS4#MGf*e5#*bL?~wR@;T=I|}nA;|Z@YLIK8UAeDR@q2OxjV?^FUU+M-T z)5&#cBmAx7w$*@89FSSx&gubl)@YuUSzz|hvMQIPp#*t)q2ajK4+D)F7{Cl3r_mFX z4Wdik!F3L^9*hHC@*>x8JI!uu_JZ4m7OmMnS0bL?C{D76yJP`8;OXeTh92s;;|AjG zd3epIq8m?Oj$quuFi#-7hIw!?ro`JeGlpDxVIhG>pom_o@)_&u@RojGDkq>I(E*-cWof?9(w5JH4JRx zKHvj literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/Searcher.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/Searcher.class new file mode 100644 index 0000000000000000000000000000000000000000..9f448ae2130bb8fad2352ce111709ea154162afe GIT binary patch literal 929 zcma))&u-H|5XQfCOq`?+ZPO%eD3tOitxY0);et{sArL3GL`oHjq>nJ z9)l|<5Fl~nz`O7U2pBtwnxItb#p{`!`OUX8^YhQw?*N{lZQxD`3|l4K#r6^!xM$$L zfd>rvSa9hbGuW2vMN&8;84Ut)>U76v$97NnId>A}2hK}zmWU2RvF8s%t`aF2o?SO@ zZ_JOQ;9N-OFnTLG`@}MbA{3G<(dCL{G$**(utgH|7X)BfcKuKsCZ_`-k2vXOsJM~G zgFcsjYEPWHI`(6R`kaJb_HrRfgdS$J%G`Y>k>N(Hxc81>bwMNQ^TjSk(}KvZ4>T&Wi&(i5-zv=im&10SaoWT;*a^0}1!BAcd(CUy+$ny_G- zc!U-OW{WVHz!bu;lH~_H96GNDC&E+I{!3&=qkY=*LtpJPHvMnDkdB`#qgGI=8=p zz4;97p!Es4AE>ljU!ZG9E%(FUU+s?+qvIxh>qG`>L|n%*Hpp&Z3!C&$lrak{SS2g9 pD_Em?1&XUujz-a-+EdRuc{a#Xg!UT+1C825qzetV{{f4{?RNkG literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/blinded/BreadthFirstSearch.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/blinded/BreadthFirstSearch.class new file mode 100644 index 0000000000000000000000000000000000000000..97d342978298ba34b4f1ebba6a6e938368337920 GIT binary patch literal 319 zcma)%KT88a5XIkI?vI|Q2{zU?5-r@uPO(r(b!ZVuzqdDd8`fLc+vIy$2^M|;Ka^xH z*x5J(k9j|49?bX8=NEt*%t}mfT;Qa@l#t)q-o|^vWPZ6Kq>sL3!nC$MKW*L`4llZK zLQZRMv|H(5NB;}c*x7+FuZ<6^2Jf~URO4*la;qK!>o#@^8-}=K9ZYviD3^W{3@_}M zdG>eZdabv*LW+!V@xN5UY&=p<_pj=?S+j{aMbF5XQgB<&Vbb9fA)ah^U3z*eN#3RY8lB>o=Rh?6GELvv==hC0O_XK9o2) ztgM`YkNJMgd@x_%AD;lOFe@>^eu0AmQ$l`YdmC>Fle647VTcRX!F1Pza^cs(@Z64x zM}HSCS9+r>q{s*-|4Agw#uMdq|EwOH6`P1-B=X)^BrRE@xj41;Kz8vCdJ~YK5X}Wc T4t7MV?VMp3r8vT#XoBhoHBd-O literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/AbstractFrontier.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/AbstractFrontier.class new file mode 100644 index 0000000000000000000000000000000000000000..060dbbb95c94bbe2557bf4c467d7f23cc4644112 GIT binary patch literal 1638 zcmZ`(+j7%Z6kU>)D0XB>LX!ZcX}HFg9aPGt7l%Na!VEJZT*5%xw-fnH5LG14u@vAh z_=0{xAIc0(rZ7X_V1{pEI$cMyV|(Jf=v;L6T5GSp&-wJ<+xGyjV6_AXi$#p%q7AQv z0v1a+k8eucxipS%aaqr<=+9OCxn|=#8{Zo!${i7=B8ioOnYCwPM|f!xgx+er-4aUg zH+X0x*os7wDrvwSdT43QkCpV=akwLuw;nfTW0`@YOFJZ|9V zS`f+gbbC{(M`APN&eU4$i}0~ffnIkut>kIYHc%NLd@55Fw3ER1RyNy-5`J=9#ZeMS zt$t<@=4Go3wK!bV&|I`oXGfM zHmU>3X6_o8Xa;RxsOCNOP_{zhGkSW^mF!^kH#!_;;8Vk3>^N-Z++~vazuy(D%xN1x zP?+jMFARY`2&Y}LBl$cB9P?QN5kxH4VxLpp56zykD=ytnyG`bp#9PW28ios!$}PTmd&LUcP6M6+p~<}2Xv?I5-GkmFIVOiW;u z^GQr`evCW6a5OoV+&vg>?QfW`xhgOUj4EVbi?KyUPIEPrpXNBr72`VS$2oV1obOER z^PS-AB);shd0go;BkmiRe{o`FL|PIkM-${ABOQWV^eM~I)#cwwe2saY*3w^5o)+lU zK4SbG3cv2b`q!=PVq_Pick3T8t6A!`e_$8z2a0Z;|HiC88ItFBl3oB+Sa9|8O8QG! zz-7*^W>V&J`2AcxoW>cFPcx&loS8Vs_##Z_Gv;l+$Luo#eHW!C z+S@$k+}j&eaFg6CeSGD8zH-K*ttq3D@flRxP5&B+bmh!~&ZytWpEI<)QszFI*->wH LI>ALPi>v<+PLXY( literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/BestFirstSearch.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/BestFirstSearch.class new file mode 100644 index 0000000000000000000000000000000000000000..e1d32b3a03bb87a981162a1f44d06ae5e7aaaa38 GIT binary patch literal 2447 zcmbVO-*XdH6#j00benX6S_)VT3e`fJPyz}fEfj%LEcBNIsS1kQ&26)gX2WJv0Udqh zZ=f%{IKzt%GGpUZXBc_)Kho)l-`Pz_Qpt?t%iVMDJ-@#1oO6>u{{HnDfaCZkiGG|( z;0=t+a#ofPlQ@U-NnF507cOE#wv)2GB+Ey#Oc}VGgo!J1H=U%>jHpuK9A>*Phxsm? z#K*E+m5ZzxU6bV#S+2|3f`LyBd}iQtg-(61RB%0=Q`j+m+gi0U72hdjvf3Y0NMxPm zqUBdStuWYndwSZYRi@;*iv_)s$@-SB$Hr;Xx#YP;-_f4JP^eRO3#;18Vw`p?=3{r|9_O3O9yY^BQYo{I8g8^cq2iuPekZ zxH)3qG3^xfY-MFpd)F-DRp^;^ZL4tI@*LUM4r6}aDJvXm^xEI zZuN4%RQGgu3#vA3w+ZzBuy&M#v=oMGb*tBQKCJQBa1+xL`ff!NLEO$e1@=x)ODeNu zjhC@vz@AZaBzRkzrtX-Up6mJw+t^0-of)eX5NhCt!kPb?OpT&ivjrJQJDTiotC-U{ zIZ=oX4NoZ~vu?$+^`s-E?A=nABQgah265BGKD=q-00vCFjdu)uVd6{NGVqlN3pWic znm7U5L=M`-5^kATMqZ&iK-rXu2?w`L+(E&_3W_FNlnmT8;h}887sCqjCRWAID!w*x zPo(=IJ-{f3ui0Z`khWyb$iV~`tm1NJZt=FZ$!Tx1Y1nx(n>~$LpYpY51(Qd1*z}>r zmg;k`1yI=i)Z^1}u-S7Xsjb~7O;TWMvAm6#d|wn!w0j_$hVWH=6}56~xm~pxX+k?D zX&FxW;!4TC&#o%Dg#z&m)jGFXlX#Z3A3R&^OKJpQ>Y&5tj2@OtJrx>T@i z4ppq|JkU7CpQnB(>_rqkGE9`;;;&x>`?=>_QSOn^;y22>K^)}WA@088H^y&o>KCX~ zdL5C};dMk)BkPDg4YY^2?nazzKQ;FvLI2wsVJ9OD^E4IO^PA?5o@(($lE{(ZOkziI zn6kK&y` zoL1lBT}n|Q?PVdJ)7NnlJAlXZe~je5&-(#%CN^=vfZ4T)ettHw&%nt|oTdC15`R)J tY@H8idkUjmrBTF_6fP-jY@ko!NA4m4x{l!HN|0Gt-efHcg|R^E^grUNZ;=21 literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/EvaluationType.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/core/solver/heuristic/EvaluationType.class new file mode 100644 index 0000000000000000000000000000000000000000..36f1d178ea57d20852de333a83189b7c1e8e994d GIT binary patch literal 1097 zcma)4?@!ZE6g_Y2)~*x=WuipL&w-mw$5tYeQ(WWjd$p5aB&IJE{=#k2fw#f(DN@779_iqeh1w!DrNx}5fsTk@?Q zrO^N7Wk_$kz8mc@Ec_>Jv(%v;M<*^-nK9k2Z$)uPOvxe-DBHGodHMMmb;FN)+mq?t zp^>O&5Qnz2@A59pU!T|}Z-j<<{w{JFs(8Y%I?1RtEaIt#yI9tc#jJ)ozUi1{n7L{$ zSIUsGy}+m3xngOoio@em$Bszfv+=&vJ*(fZjlurT=Q?X`w@Pnxh90=IyT}y)WJ!du zqyw1E^SU?!8Qj1E7;cicLY6Oe2=)bu3nV|0$8d}Gw1~-sUqt>AzlDT2RduQS6{!nI z9G|#`zfC9F2!$ow5pik_p?JnBlJo&`d41^|>CYlOp6=?pjC))P0Pn4W~s&c-0? u(lmxJ|20*?H!Qjz(Y=i@>x|l)`$Zp%l5NZggrxlkP)Zme?HGnFCdj^OO*7H} literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/MyFeeder.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/MyFeeder.class new file mode 100644 index 0000000000000000000000000000000000000000..0b54c016827600141d58fb48841abc02427b1447 GIT binary patch literal 2729 zcma)8U2_vv7=BKg-IIiEsXz(=%9j<=QW`ACM_VePP>H0aHU%tIbepW{mXLHdn~rq6 zafS=LcbL%`XB=+0RWGPxXT0;q@hA8X`~wc7;B$62b^AG7<;*P|J0{W0$wcTNXmUQ=Rf#^uBWC`rd+f{44@nF_+rp(z2S9axVMYD3- zbZj*b7NhQ*T^Bf%FP}b}S#WCHd620tG?tbsR%YzssAZKbXHZ~A*>WfRZJHlX=gmsF zem2u^?MfzB9qi7}n~SDD%{q?xFmKmg!o)m(IsR-4tJ_PIq0QDzr$n_gGu((P?FH9# zxpQ<=5fh#k&xC~0a?Pv=wE7AIMFI!6ff5z5YbqjZH4DT7hv`vr3kN#Z2JPWOGjOLi z0}SPhHOE?wV<2yEm=ap)LGk{Wxex?CUa-qm(``6(eE7A(xea+wI;5shG^#k!KR~c0yxCF2gw?M2T7BIX5wn}!KwN*Rq3Q9 zzR)aE+J&RFro?GCmL0#Iotnyy3v_MOp8prTqK>gxz4Qs3dHwcjR`wu{@~f5P=Mem! z3Fdq+$94N8MZ8h5dXtd;=W7LCyp^afns~i$9@b@P!fp1u0(k;d`Q z70BsSv~wA;0j+6FluXJ1rS~VLkCGlrVZ$hW1@Y;WmeR?Q7?8aw`5Zg$JbQJ&_Xnzs zdY(-(5MU@`48l%&v4^V%>DyZz`{>&MpO-lwrI(X9f*FRcgkxCXbCL5e@FpIk3r}zy z-{AzlN7{?h662I6-(lM598b{x2;*}vSd+LFtm!=SD>5EI3(xwJd|lKwi5t{#oQTI% zcY<#^&yeKo=ExWa@mFs>ILSQ3@GW|Ain-|HzRHrnlHtl}uJj@C4`LFLm*@}@y5LN_ zz}^?o{zaRF3@!Xk6>k$0LBE&bGk%6~juJu1XtY%t zjWm}$nqj;f&|IJ>L7KJ|v`_zpH%PXOUF-RVJU+h>+5$d7hng(?l%iN-J*0S!-Rtq$ O5I(kw&k_;AmHz-yT$O|X literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/Puzzle.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/Puzzle.class new file mode 100644 index 0000000000000000000000000000000000000000..634798193bf0f052595e6ef9f466b7c79f8572ed GIT binary patch literal 4407 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 if;YH}@TiB#Lg?bau_A&HXSac`xk) zhRI@eHkWNQUCPw5^+xOH$g#59zFG01^9*v;@-}^BNl$TTsnRrG6Azu^DhHm`D7Xil zn4Y4nvQ&0LYU+;LYL=~aoAVgxZaeeJJTx_2!lZ@-1~rUeRK`OMc`VUv$z<}^yZ164 zX;{W%hEZOgbIq6S`qXq%!xOA%7{V~Wt&)l<4F#-m`G{EZ zf3q?Smffb+(IZfRA>M`lmd35osBVh}9xnPB+s$qhDUYaGW{ngZydX?EHh7Uk+Z@(| zhg}2Zxt3A0(Xi?jhRj6;=iY=O5a5JfNc|(Ncy1sY!;pTyFpul>iyWXIvPjFIbM}vzNKlO{xJn+q z^HFF)xQ1ldbDnA##?X33}x3=r_d3 xnQDmQmLW-7JBH+Y5_uwdkxot^FY0?jkUN3M=VCr1)n7s{EwGOww)_8&b-=%4@q literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/PuzzleState.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/problem/npuzzle/PuzzleState.class new file mode 100644 index 0000000000000000000000000000000000000000..1a08a93409f65ff4ec6f6ea4382aab2677828c01 GIT binary patch literal 6944 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 ZpT>{?@FEFf literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/IDAStarSearch.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/IDAStarSearch.class new file mode 100644 index 0000000000000000000000000000000000000000..b5c28c7feea7299978cbe332edf5412e40fa357c GIT binary patch literal 2381 zcma)7TXR!Y6#jNDJtR3mTiVisfZWrx5Y&Q5OBF#Rl9o!b2wqRqO>)XfPB=L!Hx)(2 z+oMnLsLu4k7j$e8one@9#&LA?N&N#3KSGDGetRc{q?D0qy7yjduf6uSzO~lbKmYsP z4FG-kB#JfI6Txact%kh@_C*n@YMxP={Yrc`iUAymq8TZrdrs*Ns#RL8hSV@@;7}AJ zcwSi@R`#P&8XPh3LKN*7i{U6jp8-DZoo1yZXhENDSC3k z&iJk;ur{4>J((=I&Xn|$Ia&7Xl5b~{BXcJG0!^8+@18gzAW}SBkf-<7>T)G9iPjM~|P<(EAvuyOwWKm(FtcS80L@=P@2 zxFuP0+B9GnY=2N-L%hLyA>7?#0-?QhBd|1W7vyj`KQ6r^*0@7WYue3N&Y0!dO0FqG ze$Fn@cRIVR?_Ney`}PopH!3YJlT)me^h%(+hNbAa^pz)ddhYM8i*TPjRhB#y&g5)o zLfv0ayAGCU3mUCab0pAFwVLmkmY(a9@5P#yA*-kZFfd_&vF(0PJojUKROfWRt%+&~ zd#lQ+iC&yAu?ZVYti?LgJ1^5FHY0ALM-5qJx(hiIHYQE1SBFl*F|kpt@+g>aQ50yN z&xe6iCOni(_$Zs0!f6v{a8_W2%FY}mg<|>KIY%Z(^km{3&Kr2c#G81_#0BO3Z4^zs zgNr8K#d`+cH*pCc82He{NBCG^-T&vB;BP|BB{rCTo;S0x(GIIJUq?GI4V3l&XNPFYUb@@=;uK$mRMP_bOf32cg23$PCN zTus)i2tnqHKAGj|;~a}F^U)Tsm2aczlDkX{Sw1fb=55{^j;B)U=0#cQvnG93VFw*( zj^@bFdbU6)>spS$@_AKS-Btk1tSl&w-}wCx=wNgP*r~)) z%}axpLD+Xvq=L9Nbv$U~tkSSN!$JrZ^b}#_BbFx%sy60AuYFZ(?cKz0faMTi`$CCf z;B{p-dbZ@tJn41Ibl6@6VY~dc*ab4|Nh?nj%QUt|HL(?yk;Alv;;HU2_ULLpLjn(@ z39YJQ`8EYqC+eAfsAsk_=T_CawC&cq1Z8${ogCo07h5=PrG<+iJpr2&*B}xt0y79C zdS(zze2>tvYY5Mv>F(0_N;^$*TtO(na=vV>h@q1&RToxLyNTmA?sQb$;t@Pbi5FQ?uGz=y2R1fFY3YJ|)B*A6d)tXi8a~$ZoiFS$| z*Rfn+SEws=9i0M~kyNWL0bZ~xOoJ6aVyT+C!WFE%QbnTH=F#cdU#Dkn4T9*u#zP89 z1*@iKcZ#bFGzdlAVYG2v1B3Z&CM})J=X(D2GJk#ist%IG6bYMT-pb75d1mkucfVxT zZjiX2NboPD^*2)aCr|u^9h&k!glV%1+bM_X;UXUADyRs)lZIQ^i6@wZX8gf#`VJ9;KoSXA|or|tbtLb1M(o&G(V9;(CliiE)8Dk|79;F<(KH1Np4 zu7Ns3Ii1MFZ8K~S#_fGSiNi~w{E3(BUH>mwXfwvNnhV9-eX~wVi_{9SVbW7)3($L!Kmp%$;SP+&zlS2;z%Z zT#@u{eGtS-{L18rBIqn4jY9^;bs!65dNImm&iN(xLmrL&KjW$5>_7%vw%yD$yH0VWI7OI3^rKcVWbOWZ>d=KV*MBy!21=zHgi34oF zq5Z~;g=@G@7V$GRYP>E}t~DfWt!{hoz&@eaY<)(lh&KfNEx4Hp)@Ib-f;PF>%pBUd zNlyjmx$aCZ{WO=Zdd+XR(xUYN<$2**q*f+U&4o+2ow>h*yV-dU_vtLr{|&6sGKp=_ GN!L%T3+qS# literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/MyFrontier.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/MyFrontier.class new file mode 100644 index 0000000000000000000000000000000000000000..3fd43669797a7d2f9c634f83096f51dd55325777 GIT binary patch literal 2949 zcma)7ZBr9h6n<`A*sv^uK~bqFTB;$4!K$qaMJ;Mg8%2wiVqbJwFJUoc<7ShJf2d#j z!Om#t)R|5{^+SJDr_bHpBnw$bnc?QXob#OLoco-+|Ni&qUjQ!PWj{W`T^&cUq~V^1 z`#MtiR!0&`>SS5N105NBrxp)&tl)bct9YdLe$eovj(zw^Eq+!mkJa!*4W=5_)Pbep zsai;#2dCTn=iY3YFBd|X1P^Z_DoOCP4yO3KrrzG zan{6hWvyab#5*10MK8J+%;(@#o(3GUy#|a%u#D|V|E5@{+*G6>#c-cx&c`0aX3op5 z+b@Zm%uN*q($4z2()Pg^%2SVMT=grIsyUSkGiRJ02@4FeVAeA#xGj*Hl+VcAV&|B4 zRh6tw&{yoz+NQKT@@7=OrJ}nks%~1Atk)-JXJ-X2=iV!{XjvlC7D&7xfWGWBTua`v zm7<5b`aG**8+e8p1E1iOz@c~aH?{sAsZX9$5ETQ*a9m)27bomub-HEXBtF(qHQ-=D zL(RZ*xCZL*1cvvP)j$JH1Ha&ffvdP};0oppe1Qc6U*anR+sbRCTfLhvELrnxhv+xe z`AsY;OAc3YP2l)@5)e2QWzcQs>uYt-H7&2*)O_k>)2uYq+aWOd0e8bzqt-YMci9FC zphVQu7d$>e(V{OJTS`TeOY2Jd#qg4&7L-tuT}<+ELh98P1Jc}Y@1UFfoOic9A!`jn zUW$S2MU0Z_$hyy!TTWBr1ivds`Bh8spTdB^gugn$ky7ZaCo#x5B}mKDJZqxQ_nFL3 z?;w$Xi{$ECq*n7gNbjKU4K!|LR(H_<2Kw)`Pa?-L%MT?OGmV2dj4|S$#1wZ%11#h* z%@r_-Gniq#vz#0J4R#70HnYSzhfldyTyD`@@z3U8L!WM8;13ur4E~LMueh7=Blr0z zGm&W7PP8n}^Q+FM3>WcPh-r~=lHTJX=1>58riI}ZZfTtCUr~t#@cVq@OBi7f9L1a; zW+DLSgc--@xa89q$7RkEoU>#2tCCR3s6;agy@l*v>NkAMpct7DbHa~5Pd_#t#~7TE z-+UWY{GbHI7#yJ*F!X;!*1i~aC(g14iF2}lCDla@GJnj>pD=SXQs85q%#Y!^pSe)o z9>#geC@Rj$Am0PLtl-yJ%qZANO#sD@j4x6&w!~`mx*aJ8a zMpPmWM0JB6tiWT9-a?XKx{PU9Q@2}q#iTixOP M0y<&T!@%>V!Z literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/VeryEffecientFrontier.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/g04/solver/heuristic/VeryEffecientFrontier.class new file mode 100644 index 0000000000000000000000000000000000000000..b2889384d8688e87b01fe00c568583cf4fceceee GIT binary patch literal 3204 zcma)8U2_vv7=BJZx=p&!l0v1WAbwDqv=9VTB&AT1LM0S!ODp)f-EPxu(`?vm3Pt%) zQE|M{OUEC;jTd!Bg6NFnl^0$+<8N`sujlM;(`~ZOaFLU9&U@bHecsRHw|{>88Ng9| zp2QwZD40wlf~f>{X^ms zh;3`Dd9&i=1QL^Gp`VAw9K2=7ESb)*KzDxt=Crk3)@;qO>|AiWHe2LPDsSmpaayxYdG;@3&VpGH7|a(A9bI>3!Km7df~jYx4SV&>{Jf!? zM#&lVgGMisdflc#S2!0b*ko|EylylTs_{P&JrM3|=xgb}QZO8u4uSrDFN|f|qQlGC zNk?;xT)H{70)jEv9`>4ewoxu>I`Q`Vc)^@EgSi~6;+)4J)%<|g2-a#khMP3TsXtg@ zWBxtEoCy_#dd|F8%p1gw_NT`L;ufSMTCvL4v634pu}D%>+rkj(ODtcv zIusBgRo28UFd3SLSLV~Nh_>?h4EF^Vm=v23jnI@C1tBaz&ma|{0B?4qH|hU4?5 zTgfyzX;p3A7&T=H_k%lMgfrK5qwJVgNyV!eQ*jQ=MdtB4QlKwLbfbSqW-E@Z>Gjs-5ZLg4 zz0lm6VPZO5Q6MYKtDI)uJn;e-98zozw~8*#%Mu<7W_5jx5t`jddSS_J&bK!{$BpY$ zVI4F3v66d87}Am)ajc&W4>l$rHNBCRUGFo!aZA<-;(oTo}^!`hrbPA{4h(`GK6`Ud3DCH?c|3*?MIQtj&DQNqX{s=kJd=KyOove;Q$u(NT z6Lcu=?|05@=3PVg%)nY+tWg(?ZyG(m2R&%v%~e*TO>Py|ze8!2jIX(@Wd*COY>y$W z`K%>FX2Mj6B;>U9SzYp3wFg+$4Yv_$-LO|`H+gf5t#>Do&i2hF@}7zF_0(SWP4qPS znEVw=>^_6Bksz;FzNotb+Fx(R9^WbHN*s}$r)1^wXUX^Eyl(CN)loyp_HcFk`x+lMWD45L#x5kAg2^#RX9!4av)7gE(oYE zzVOC)nep=GjITau(835hJUTKy`3v+9_@=(-xYo`gJ>fF#m}&Of>-O!n_F8MFKmYsv zj{pwhJs%XD^=uQ)8w2;wf{9Fnxx#P%>-vN)= z)Nz$YW+tO!KMn{4_S{ef|n#O{k-hvWe+a{yrd9+gyI}82DmP; z^%+5)E>|s{Y>x4Uj(6}brMnUe-xytOzF02NJ%r;4$8Bb3FVU+&cQxqjk95(jR)-vB ztsZShCBKN%&o;|&DcuWp|E##!hduRt%_`NVdD6%;o}luFoxsh27&a2mIQ<_z6y&v3 zr_O7eEKb~+#k0>J-A7OCPI~6`(M?<@fGCwpQmU4uR4_@YW|C6bB&EtpO2s3D5Vr@> zD7OTtcWLj!Ao0{OE&lmHlpBzADttJKA<_&J*GH5;{szP{To2&>nmB{eB#S+Q|@Gu?C-tVwQ^LX6&}JtWZqr5DbX{$_Xq&FPP1o~C=Lm!1q`!dYzCY)7XLE`x+YEt(At_Ya zh2fUayX;9G%jXK>&z2nDe znvM%J30JTV@56)p=)zAl^AE8ZzhVo1BfmfBAGLqbD>@Jpo6skAVVfAlc9Et>KZ|}b zhuz{j_J~^;5MLrC?qaX_1^dMB*f0K~w_}t}=Gl9QYsk`xAmk;yN;~=uvZwD143fJr F^&b=sUdI3c literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/FeederXu.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/FeederXu.class new file mode 100644 index 0000000000000000000000000000000000000000..233385a3d411b0b95e641210d72c87108390749d GIT binary patch literal 2912 zcma)8T~ixX7=BL3W|Oe=(_mvo`ax*|w6PShB@_i(N;J^e&<|R*U6O5B8g_BB!M4|( z@fY;M(F;dstTW!I7toQZKS2M1xBiRjSf8_-WCCp%E^>1AocDd+=l$IMgMI|89G(=y$0fwn~QxjbX~QTQ&dq9CpuJ?cIbVbty@{+| zE>(t7Ro5)1GFCd7UDnrh|8c@`^oLoq;!-VKFv{imhpS{DGW;#`XOgUAf5Ek2mjyKG zfT@@BuI^H-C7GOEp`2|IHCVEBYN|EP0zIuf$kCf=-y7-$Ok2igD|M2r;n1;I3qOJt z^AX7@CC4mM?D*~5tt?)qgmjqZI=9B0hqbt$dYzTAY{7PnMjmRxPLC6)gRv>xpVe1A zeHC|AoDqoR&61_NRfojJca@MGO!Ot1IOPkvWf@M(tg01XK;YnOv;-!14YmU#S#i^j zZMml52;>recq(>z&2UmnM%7`3nT6D)HN9NbWnp+xPqq-7Sgg2?UT7f7DssKL>}{d3 z4VZ=MwSZAH3$9H@47ryurz&HWnyE9|kw(s`>C^t<9rOjFw3aFA%sg!!N^JEjZ|F{8 zi5U{uN4dNtQa__=-mW?YW7?FB-%)Sk)3QS~yop0h+iSX2gN{XkW4o#B?iK^1Ui=yg zC~7cpPoR}-y`Lqe679BtZ0cYsxun6wvWENM0FXMb6a+`#eWO^f92F}XEZ9BS;v zV6A)0I$r@-7MG2Jn@*C*J}(Znc+Yw7nTX+cUvodal8|kU)cmTLvR77hM`u5=lH<)& zqv=L6i>%fghjPvN*wS`PKyLcZ<*S*C9O~?g3BP;J?!Hs&O_at_zGXZ44hK{S*)?3_ zd`j_O@L%cMfcS-*0N&yn@(vH-F!!1-fVa`bCxLg+O(`mizn~z>vmZARSlB?@Z2vlf z<6Y08j0W3Al$g@>9fspU{y#@3-!>A8g?Q2>rAAbFJ{SuC3+#D_sBN zefTTPdt!>WhBgsdh$*qq2BM>CtBdd^+85$#JlwSbZ8Q>(#DnYT7>GyKvFFCqmp={s zOs+xCzgu1~jvAb0&3U@pS=7N^KBKzm;^nMct^U!IWd8G1TM9hp5} z>MW&(c+vyqC5ePo#8eEc2nZD;tbu>AU%Wu~3n>5aGwnS}2FO%3#_`fEDRSX|5G0d3!9u8 zKlh`W&bw@RqtX3v&Yt%??{m&`&hD?@-+uy_!kd2(V`U$rAX}ZMM}~g(+sV)z~FCFaWxUzqzTn_G!o~|XxoNTt5=9h z2$~stFhtW5Yo%6)3_Zb6yCPyNuUlp43Q^9ULM4rQF?Ol61zMRWQ>s_;>axaX)%kaq zQ+!Yo2KmP{Bw-mThLKD5FCl;x33sq6VE{Ks{rPDx)iu4KRybx_!gIV}0QYGLlbGVi zK?y$iCG>IA4?jcK2?-ZP-&kHR8Px09v8?BI)qIWgoLO>0SE|+Msk!{y`dL=G=WDkr zK31nvE~`d?VUYH7fy$CZ1e0wD{*Parp&zW5eqP67KbH)UC)K7W;gpg26anu5UjxNX zxG{_oFpN?ZAkQC91FQ+#G3=ixqTiIP)6CfkAHbM}pM%Xj^~gf_8yv?FINo*!KTao7 z3x!*_ZRTkwgc_yy71*g~LWCy<58(_CeTD0@iQzT7C<}B@ZHa6rIG2xZa>kIUhre+} zc7*BFh6$=PfV)n*dy39)(TRv)+M;_82ay4(BM4c!%kG^%ME3!_W_V5Tj+voshSwe5uo?C^ we-PT6X_e88iVQBR zxPn;)S5+uT$<3UMt_5&iK5xinM!`+_W?sQ9fnd?Jje=uZ6@jt!*R@R5w(=#ToT=*0 z&U3R;G%MSgmE)YOfPcZPn9icWMB?A+$t?k2&MF!LJ?m!0cvvgv4f~1C4g!7aRzWXq z>9#5N?xD}wG4}*wov=5oeS<8tZNq7?5*SY;I~BCDSmi6)`YQo%Lh=giIYu>S?KzEu zH6A$Drekwnfhh5I^?f~4(m8(fRL*X^tm!4v>rb@3ew5#(g4yIV0Y$G^&W>Rd(#r43 z5l>LuG=c6-M=!kC(5vpq>ZVn*3&yG`MG49QXJnOz2x1z}piemuqIJXxJK7a8JW3?h8OZ9|(+ea9DQLFouf)k%DC#t!uF4-i_Y2 zCI?imEJv(SyZ+{grj>b2?Hn>N^fI-IGzv~1Q=qC$D)F+NlF(IH+A`XKVarF_SZKKR zUl)+R`u7gXd8^d0nR5B{YSpL|1Jw7Jb=I1G`vxxII*vnrhO_!cA z@-vPg%C(=nRe1OT)YK6~D*Xwb_uP3fz%>jn*C2dQxrQ*v-9R%NLpaMF>l&znXu}wB zF*AJ9TXdy9!t;(n6HYdkpb|!FCb%#h8Zn+oLi5a)d7%&Rrt0w3(RIQ|ZFG;YYqSj} z)PgyW3ogtopAse@Iedoyka0VWp|<)!tDYCxtzU6z41b04^r#6_N3agHFI0zCNB5tD z#o7>uTZp{7F5&?ZrJnJ0>Mgo_hv^>(zdEnp8DWX1{o(9dyxDM7!50M literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/PathFinding.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/PathFinding.class new file mode 100644 index 0000000000000000000000000000000000000000..8ce6cc4fb78722f4504d9ab5c48808d8facdf40e GIT binary patch literal 4854 zcma)9`*&1V75>i5ow+l^r9fZ;F$shO!sJaOjgUYJ4G*J92!w|uwsw--BmyS`uaL{k2S;-R)5qSZHR|cBSVqcU?eu&u#Og+_QcH=1@H1mERt$f zs0nopSP3&{-;)Zb%$D2jRc%qw+N?oSVOmEdW_FE@_M3@KVP2z9&|wXPqg%p>h^#Z4 zT52RhL<=Uv(@kt^9c+YT2%<dR3bpqPyWPf}jO-;!)vn+hHd7J^ z0$UiWx~E|IlDQ+5p?f$XH>!xjR8kq((HV|s;^9kL(Vb4b+@Y#oVo9dVc$<|>-5a4* z1F47=YpEg&Pg3&4JcjK(h2X?+WlVWR+)6U6R!m|3qPC`0v z#tX&)jtf-Dn6hm^v+SOx4#~kRhLLJ+~JHriJ zMjKX}kBylvc96F-&~c(3wRRG9>0|^u`7_C>L51?kY*t4SrW0TKi`g;1NMJdd<1rX8q^|dJ!PAmn+Gn4*>Hy>GktN+#(9fLZ4q2TX{49CK$u>^^QZlQnM zqY@I|U?RLrvP5lAt8KRWWsmSe_JV<%+*CjgwFu7kVaZLWl2m-VBomJX_=J>iME;Pnn5u%3@Tfj|;{gHn35OB%DZu z_Y7F^Jqpzst=g$r-@lzj)zUsrE7>i(FMHXHH`;|ClCCDpHjC}uv!=6q(>8^f6OcRI zgTJoZxT>dzF`;>`Z26v{CMO9;&Wai>yPFMhIK4@sGIV#3Rnoq+t*bgZcrdwVv|k9Y z*4PT%))-rR&|x338oH&Hs30>uN+4c#Pcz0st-DRgZY{5j=6G;|eWv#AWIxl+*u?wU zfbGhTQd`0C_h8!@iigS_C9_2X_L+R?3;~p@3@js+nwlpY@z}uJSuG|uU`iX=JPYFf!}qC|Jau} z8l1CNaa_VxJKX%k@4o7q+A~lmId$OyjsZS_0(dbKO`MfEX7~)2awQ*%Y$Uc@UAhUa z#qIKp+kR;L!}D}odIqlQ($e?fcD)HLf5UyY$3l9VjT!t9lv}EuQ@L9Ta<>#@ZV^oE ztvsvnAXaAXYv5BTda6%DJHd%V!fS69+pdK-4Kl73R^cJ;NDLn5uEe0iy`qHYJx5Sn zQ_|=bSI)z87TyCcb?nA}1ijmiPl1he9^+Jo63pXwZFw$EF7CAvqeQSG$ECtffWm6- z`r*0?m%74(3Tv=7gQS*ELFv+t%V=NZaHtu_!Ik5%4xi1OJWW_0o>^LR5qg(EuS>(H z4L0)O=c8FG(oP|86u#OtrW}`raTEbr_(qNw+$Z-r#O5*~q7@I-QpA+br&cN%r+T7! zfG8wQOPsrM)Rt05ju@8WbND=wdw8k?o%C5mj$K&Ka0zh(u4|~&q3h_rk9!-iF~i`W zwDr=Wul6FQr7`_1W^@S|(x}twA8pc{g}=_tg(s*TMq^NubiInIpyx0a1SR=g6$|^I zM$$nKhf^qc4Z3y=nmbR@$zBVlP_c8Ur-jUx5NmZHoR>{9< zl18=Ny)Naums8{>)i{J%7$(ypGK{biOvYx19X09225Ri6xru32uBWZeMuV&*1`fOF z(4?nbg`d=_uQ28cqlh^?)HKG&Paga8m?sq+f6zK=F03HYk|WqqQ);&_5#WU;ue(VP z>Ot=j)D?MxdSkOM?@(kn>!u*+ER}y`f*@scA|HfuCJ_`<1yUq5#$L3OaL2gXjlCTA zag?S|M(7(T5b0t*TDHML+)m2=Oduq=_0X=PPKR5m8wkRuquyTVc#MA)1^GWLz9CWJ zFSJ)kWE%ti%NwM7_tv}*gJ274Sav6!y6ddXRNXR8oTBSuQ@0C^T|8U8MH)*k4L08XB#t?1GSY zWp7Rby_tf@NuIy;Q%;U347jIWh1V8%Yfj)w{vY88gI_1vSN9pz-Tdl)(S~vJt9y(9 HT-f=4+_qC( literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/Point.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/problem/pathfinding/Point.class new file mode 100644 index 0000000000000000000000000000000000000000..04f7727583c7bb98ba63f59becc4a7ffbd901e31 GIT binary patch literal 4115 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 HCUN2aot>KQ literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontier.class b/SearchFramework1.0.1/out/production/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontier.class new file mode 100644 index 0000000000000000000000000000000000000000..a696cd5907044d21b8d03e85f92bd5456bdeeb74 GIT binary patch literal 2539 zcma)7+fp1=6kTWTGc<&7iXT)VpmhMA_cC{CY!&e?mfwe~(|e*5RgUjV#{%@j`H z?KtLA2;rS1hHzbG^Ia(5T^Zhsqm)7d3n`RwL-yX6Qy+BUCKkoKCBug)t}V&zwhSMM zc}Ir3GJG7zCvkkLkf>QJM#-!@3PYt0eMc`e9J5*|nYB%0Mb;-3l8feAO?Mi$p^yzc zG*zltwo#~C)g8kwlo@hzhK{i*vt~Lo3d89Zw^?gzTeo$`vL`c33XxeJS2)I$M!B)I zY}mK-)X$F6p)@w!av0*3G)Y+0y++Gu^t;unE+x_^9V>tLB)7Ey#@>z1ome zhv~IIkc~rmzT9r+YUO(1aRk?VFvY;rLOZ@@I3konI_;^qZCm8IRakU%$C%7?N=mJy zTB1yc+zN`a3H83 zMvq#ns|ITu*|w@x(r2I!RI+Oro8E2!pVXq&uq(!#DLvQkHGZ>&F3Ncgr*N9?LAOKp z?rC@q!y2w&Lc{0a`DI*F=xs-$p@Nk-3=OMzS;I>*yoj@LtZ7(>sqyY_XqdvZ%r0xV zifbB*-teZF9AlxKuv zmMa1~zYj5w3$zq2a#ch4DH3rM&iq9vN?Or}HceafND4IO?|MihyX-g_Ph9; zB7&ZXK=7E4@mCK_6k?JQyhc8+6Z;jeOwgL*6`672Whw6n2Dz4Vg)Z&`ExO7mMz~7f zH~1Aj`VjsbDMdk^;#?ewKM7pPedfLt?2=0jNccpg7OkSpx>>!#C;VJqzfIDUH`JjAK4yB@c)nN8%~Q>GJp-XT!Bqy4eDy z%MYgb8XXa$FCfJ2&JevtHb}GAq>f&%<>(zisHY`>-)juO7tyCt@M%P|d+2W`(CQrZ g2+)~tYJl^=|8t%>68d0!En2fTuZhB}+c$6h3!xR_hX4Qo literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/checkstyle-idea.xml b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/checkstyle-idea.xml new file mode 100644 index 0000000..cab6d1e --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/checkstyle-idea.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/dbnavigator.xml b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/dbnavigator.xml new file mode 100644 index 0000000..898600f --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/dbnavigator.xml @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/misc.xml b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/misc.xml new file mode 100644 index 0000000..3987345 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/modules.xml b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/modules.xml new file mode 100644 index 0000000..1a1891a --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/workspace.xml b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/workspace.xml new file mode 100644 index 0000000..aa9e9be --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/.idea/workspace.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1617149915487 + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/jdk1.8.0_131.iml b/SearchFramework1.0.1/out/production/jdk1.8.0_131/jdk1.8.0_131.iml new file mode 100644 index 0000000..e3c5754 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/jdk1.8.0_131.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/defines.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/defines.h new file mode 100644 index 0000000..d9e9803 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/defines.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _DEFINES_H +#define _DEFINES_H + +#include "java.h" + +/* + * This file contains commonly defined constants used only by main.c + * and should not be included by another file. + */ +#ifndef FULL_VERSION +/* make sure the compilation fails */ +#error "FULL_VERSION must be defined" +#endif + +#if defined(JDK_MAJOR_VERSION) && defined(JDK_MINOR_VERSION) +#define DOT_VERSION JDK_MAJOR_VERSION "." JDK_MINOR_VERSION +#else +/* make sure the compilation fails */ +#error "JDK_MAJOR_VERSION and JDK_MINOR_VERSION must be defined" +#endif + + +#ifdef JAVA_ARGS +static const char* const_progname = "java"; +static const char* const_jargs[] = JAVA_ARGS; +/* + * ApplicationHome is prepended to each of these entries; the resulting + * strings are concatenated (separated by PATH_SEPARATOR) and used as the + * value of -cp option to the launcher. + */ +#ifndef APP_CLASSPATH +#define APP_CLASSPATH { "/lib/tools.jar", "/classes" } +#endif /* APP_CLASSPATH */ +static const char* const_appclasspath[] = APP_CLASSPATH; +#else /* !JAVA_ARGS */ +#ifdef PROGNAME +static const char* const_progname = PROGNAME; +#else +static char* const_progname = NULL; +#endif +static const char** const_jargs = NULL; +static const char** const_appclasspath = NULL; +#endif /* JAVA_ARGS */ + +#ifdef LAUNCHER_NAME +static const char* const_launcher = LAUNCHER_NAME; +#else /* LAUNCHER_NAME */ +static char* const_launcher = NULL; +#endif /* LAUNCHER_NAME */ + +#ifdef EXPAND_CLASSPATH_WILDCARDS +static const jboolean const_cpwildcard = JNI_TRUE; +#else +static const jboolean const_cpwildcard = JNI_FALSE; +#endif /* EXPAND_CLASSPATH_WILDCARDS */ + +#if defined(NEVER_ACT_AS_SERVER_CLASS_MACHINE) +static const jint const_ergo_class = NEVER_SERVER_CLASS; +#elif defined(ALWAYS_ACT_AS_SERVER_CLASS_MACHINE) +static const jint const_ergo_class = ALWAYS_SERVER_CLASS; +#else +static const jint const_ergo_class = DEFAULT_POLICY; +#endif /* NEVER_ACT_AS_SERVER_CLASS_MACHINE */ + +#endif /*_DEFINES_H */ diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/emessages.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/emessages.h new file mode 100644 index 0000000..caa5fa4 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/emessages.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * This file primarily consists of all the error and warning messages, that + * are used in JLI_ReportErrorMessage. All message must be defined here, in + * order to help with localizing the messages. + */ + +#ifndef _EMESSAGES_H +#define _EMESSAGES_H + +#define GEN_ERROR "Error: A fatal exception has occurred. Program will exit." +#define JNI_ERROR "Error: A JNI error has occurred, please check your installation and try again" +#define JNI_ERROR1 "Error: can't find JNI interfaces in: %s" + +#define ARG_WARN "Warning: %s option is no longer supported." + +#define ARG_ERROR1 "Error: %s requires class path specification" +#define ARG_ERROR2 "Error: %s requires jar file specification" +#define ARG_ERROR3 "Error: The -J option should not be followed by a space." + +#define JVM_ERROR1 "Error: Could not create the Java Virtual Machine.\n" GEN_ERROR +#define JVM_ERROR2 "Error: Could not detach main thread.\n" JNI_ERROR +#define JVM_ERROR3 "Error: SPARC V8 processor detected; Required V9 processors or better.\nUse JDK5 client compiler for V8 processors.\n" JVM_ERROR1 + +#define JAR_ERROR1 "Error: Failed to load Main-Class manifest attribute from\n%s\n%s" +#define JAR_ERROR2 "Error: Unable to access jarfile %s" +#define JAR_ERROR3 "Error: Invalid or corrupt jarfile %s" + +#define CLS_ERROR1 "Error: Could not find the main class %s.\n" JNI_ERROR +#define CLS_ERROR2 "Error: Failed to load Main Class: %s\n%s" +#define CLS_ERROR3 "Error: No main method found in specified class.\n" GEN_ERROR +#define CLS_ERROR4 "Error: Main method not public\n" GEN_ERROR +#define CLS_ERROR5 "Error: main-class: attribute exceeds system limits of %d bytes\n" GEN_ERROR + +#define CFG_WARN1 "Warning: %s VM not supported; %s VM will be used" +#define CFG_WARN2 "Warning: No leading - on line %d of `%s'" +#define CFG_WARN3 "Warning: Missing VM type on line %d of `%s'" +#define CFG_WARN4 "Warning: Missing server class VM on line %d of `%s'" +#define CFG_WARN5 "Warning: Unknown VM type on line %d of `%s'" + +#define CFG_ERROR1 "Error: Corrupt jvm.cfg file; cycle in alias list." +#define CFG_ERROR2 "Error: Unable to resolve VM alias %s" +#define CFG_ERROR3 "Error: %s VM not supported" +#define CFG_ERROR4 "Error: Unable to locate JRE meeting specification \"%s\"" +#define CFG_ERROR5 "Error: Could not determine application home." +#define CFG_ERROR6 "Error: could not open `%s'" +#define CFG_ERROR7 "Error: no known VMs. (check for corrupt jvm.cfg file)" +#define CFG_ERROR8 "Error: missing `%s' JVM at `%s'.\nPlease install or use the JRE or JDK that contains these missing components." +#define CFG_ERROR9 "Error: could not determine JVM type." + + +#define SPC_ERROR1 "Error: Syntax error in version specification \"%s\"" + +#define JRE_ERROR1 "Error: Could not find Java SE Runtime Environment." +#define JRE_ERROR2 "Error: This Java instance does not support a %d-bit JVM.\nPlease install the desired version." +#define JRE_ERROR3 "Error: Improper value at line %d." +#define JRE_ERROR4 "Error: trying to exec %s.\nCheck if file exists and permissions are set correctly." +#define JRE_ERROR5 "Error: Failed to start a %d-bit JVM process from a %d-bit JVM." +#define JRE_ERROR6 "Error: Verify all necessary Java SE components have been installed.\n(Solaris SPARC 64-bit components must be installed after 32-bit components.)" +#define JRE_ERROR7 "Error: Either 64-bit processes are not supported by this platform\nor the 64-bit components have not been installed." +#define JRE_ERROR8 "Error: could not find " +#define JRE_ERROR9 "Error: Unable to resolve %s" +#define JRE_ERROR10 "Error: Unable to resolve current executable" +#define JRE_ERROR11 "Error: Path length exceeds maximum length (PATH_MAX)" +#define JRE_ERROR12 "Error: Exec of %s failed" +#define JRE_ERROR13 "Error: String processing operation failed" + +#define DLL_ERROR1 "Error: dl failure on line %d" +#define DLL_ERROR2 "Error: failed %s, because %s" +#define DLL_ERROR3 "Error: could not find executable %s" +#define DLL_ERROR4 "Error: loading: %s" + +#define REG_ERROR1 "Error: opening registry key '%s'" +#define REG_ERROR2 "Error: Failed reading value of registry key:\n\t%s\\CurrentVersion" +#define REG_ERROR3 "Error: Registry key '%s'\\CurrentVersion'\nhas value '%s', but '%s' is required." +#define REG_ERROR4 "Failed reading value of registry key:\n\t%s\\%s\\JavaHome" + +#define SYS_ERROR1 "Error: CreateProcess(%s, ...) failed:" +#define SYS_ERROR2 "Error: WaitForSingleObject() failed." + + + +#endif /* _EMESSAGES_H */ diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java.c b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java.c new file mode 100644 index 0000000..3e3ed86 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java.c @@ -0,0 +1,2081 @@ +/* + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * Shared source for 'java' command line tool. + * + * If JAVA_ARGS is defined, then acts as a launcher for applications. For + * instance, the JDK command line tools such as javac and javadoc (see + * makefiles for more details) are built with this program. Any arguments + * prefixed with '-J' will be passed directly to the 'java' command. + */ + +/* + * One job of the launcher is to remove command line options which the + * vm does not understand and will not process. These options include + * options which select which style of vm is run (e.g. -client and + * -server) as well as options which select the data model to use. + * Additionally, for tools which invoke an underlying vm "-J-foo" + * options are turned into "-foo" options to the vm. This option + * filtering is handled in a number of places in the launcher, some of + * it in machine-dependent code. In this file, the function + * CheckJvmType removes vm style options and TranslateApplicationArgs + * removes "-J" prefixes. The CreateExecutionEnvironment function processes + * and removes -d options. On unix, there is a possibility that the running + * data model may not match to the desired data model, in this case an exec is + * required to start the desired model. If the data models match, then + * ParseArguments will remove the -d flags. If the data models do not match + * the CreateExecutionEnviroment will remove the -d flags. + */ + + +#include "java.h" + +/* + * A NOTE TO DEVELOPERS: For performance reasons it is important that + * the program image remain relatively small until after SelectVersion + * CreateExecutionEnvironment have finished their possibly recursive + * processing. Watch everything, but resist all temptations to use Java + * interfaces. + */ + +/* we always print to stderr */ +#define USE_STDERR JNI_TRUE + +static jboolean printVersion = JNI_FALSE; /* print and exit */ +static jboolean showVersion = JNI_FALSE; /* print but continue */ +static jboolean printUsage = JNI_FALSE; /* print and exit*/ +static jboolean printXUsage = JNI_FALSE; /* print and exit*/ +static char *showSettings = NULL; /* print but continue */ + +static const char *_program_name; +static const char *_launcher_name; +static jboolean _is_java_args = JNI_FALSE; +static const char *_fVersion; +static const char *_dVersion; +static jboolean _wc_enabled = JNI_FALSE; +static jint _ergo_policy = DEFAULT_POLICY; + +/* + * Entries for splash screen environment variables. + * putenv is performed in SelectVersion. We need + * them in memory until UnsetEnv, so they are made static + * global instead of auto local. + */ +static char* splash_file_entry = NULL; +static char* splash_jar_entry = NULL; + +/* + * List of VM options to be specified when the VM is created. + */ +static JavaVMOption *options; +static int numOptions, maxOptions; + +/* + * Prototypes for functions internal to launcher. + */ +static void SetClassPath(const char *s); +static void SelectVersion(int argc, char **argv, char **main_class); +static void SetJvmEnvironment(int argc, char **argv); +static jboolean ParseArguments(int *pargc, char ***pargv, + int *pmode, char **pwhat, + int *pret, const char *jrepath); +static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv, + InvocationFunctions *ifn); +static jstring NewPlatformString(JNIEnv *env, char *s); +static jclass LoadMainClass(JNIEnv *env, int mode, char *name); +static jclass GetApplicationClass(JNIEnv *env); + +static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv); +static jboolean AddApplicationOptions(int cpathc, const char **cpathv); +static void SetApplicationClassPath(const char**); + +static void PrintJavaVersion(JNIEnv *env, jboolean extraLF); +static void PrintUsage(JNIEnv* env, jboolean doXUsage); +static void ShowSettings(JNIEnv* env, char *optString); + +static void SetPaths(int argc, char **argv); + +static void DumpState(); +static jboolean RemovableOption(char *option); + +/* Maximum supported entries from jvm.cfg. */ +#define INIT_MAX_KNOWN_VMS 10 + +/* Values for vmdesc.flag */ +enum vmdesc_flag { + VM_UNKNOWN = -1, + VM_KNOWN, + VM_ALIASED_TO, + VM_WARN, + VM_ERROR, + VM_IF_SERVER_CLASS, + VM_IGNORE +}; + +struct vmdesc { + char *name; + int flag; + char *alias; + char *server_class; +}; +static struct vmdesc *knownVMs = NULL; +static int knownVMsCount = 0; +static int knownVMsLimit = 0; + +static void GrowKnownVMs(); +static int KnownVMIndex(const char* name); +static void FreeKnownVMs(); +static jboolean IsWildCardEnabled(); + +#define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg) \ + do { \ + if (AC_arg_count < 1) { \ + JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \ + printUsage = JNI_TRUE; \ + *pret = 1; \ + return JNI_TRUE; \ + } \ + } while (JNI_FALSE) + +/* + * Running Java code in primordial thread caused many problems. We will + * create a new thread to invoke JVM. See 6316197 for more information. + */ +static jlong threadStackSize = 0; /* stack size of the new thread */ +static jlong maxHeapSize = 0; /* max heap size */ +static jlong initialHeapSize = 0; /* inital heap size */ + +/* + * Entry point. + */ +int +JLI_Launch(int argc, char ** argv, /* main argc, argc */ + int jargc, const char** jargv, /* java args */ + int appclassc, const char** appclassv, /* app classpath */ + const char* fullversion, /* full version defined */ + const char* dotversion, /* dot version defined */ + const char* pname, /* program name */ + const char* lname, /* launcher name */ + jboolean javaargs, /* JAVA_ARGS */ + jboolean cpwildcard, /* classpath wildcard*/ + jboolean javaw, /* windows-only javaw */ + jint ergo /* ergonomics class policy */ +) +{ + int mode = LM_UNKNOWN; + char *what = NULL; + char *cpath = 0; + char *main_class = NULL; + int ret; + InvocationFunctions ifn; + jlong start, end; + char jvmpath[MAXPATHLEN]; + char jrepath[MAXPATHLEN]; + char jvmcfg[MAXPATHLEN]; + + _fVersion = fullversion; + _dVersion = dotversion; + _launcher_name = lname; + _program_name = pname; + _is_java_args = javaargs; + _wc_enabled = cpwildcard; + _ergo_policy = ergo; + + InitLauncher(javaw); + DumpState(); + if (JLI_IsTraceLauncher()) { + int i; + printf("Command line args:\n"); + for (i = 0; i < argc ; i++) { + printf("argv[%d] = %s\n", i, argv[i]); + } + AddOption("-Dsun.java.launcher.diag=true", NULL); + } + + /* + * Make sure the specified version of the JRE is running. + * + * There are three things to note about the SelectVersion() routine: + * 1) If the version running isn't correct, this routine doesn't + * return (either the correct version has been exec'd or an error + * was issued). + * 2) Argc and Argv in this scope are *not* altered by this routine. + * It is the responsibility of subsequent code to ignore the + * arguments handled by this routine. + * 3) As a side-effect, the variable "main_class" is guaranteed to + * be set (if it should ever be set). This isn't exactly the + * poster child for structured programming, but it is a small + * price to pay for not processing a jar file operand twice. + * (Note: This side effect has been disabled. See comment on + * bugid 5030265 below.) + */ + SelectVersion(argc, argv, &main_class); + + CreateExecutionEnvironment(&argc, &argv, + jrepath, sizeof(jrepath), + jvmpath, sizeof(jvmpath), + jvmcfg, sizeof(jvmcfg)); + + if (!IsJavaArgs()) { + SetJvmEnvironment(argc,argv); + } + + ifn.CreateJavaVM = 0; + ifn.GetDefaultJavaVMInitArgs = 0; + + if (JLI_IsTraceLauncher()) { + start = CounterGet(); + } + + if (!LoadJavaVM(jvmpath, &ifn)) { + return(6); + } + + if (JLI_IsTraceLauncher()) { + end = CounterGet(); + } + + JLI_TraceLauncher("%ld micro seconds to LoadJavaVM\n", + (long)(jint)Counter2Micros(end-start)); + + ++argv; + --argc; + + if (IsJavaArgs()) { + /* Preprocess wrapper arguments */ + TranslateApplicationArgs(jargc, jargv, &argc, &argv); + if (!AddApplicationOptions(appclassc, appclassv)) { + return(1); + } + } else { + /* Set default CLASSPATH */ + cpath = getenv("CLASSPATH"); + if (cpath == NULL) { + cpath = "."; + } + SetClassPath(cpath); + } + + /* Parse command line options; if the return value of + * ParseArguments is false, the program should exit. + */ + if (!ParseArguments(&argc, &argv, &mode, &what, &ret, jrepath)) + { + return(ret); + } + + /* Override class path if -jar flag was specified */ + if (mode == LM_JAR) { + SetClassPath(what); /* Override class path */ + } + + /* set the -Dsun.java.command pseudo property */ + SetJavaCommandLineProp(what, argc, argv); + + /* Set the -Dsun.java.launcher pseudo property */ + SetJavaLauncherProp(); + + /* set the -Dsun.java.launcher.* platform properties */ + SetJavaLauncherPlatformProps(); + + return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret); +} +/* + * Always detach the main thread so that it appears to have ended when + * the application's main method exits. This will invoke the + * uncaught exception handler machinery if main threw an + * exception. An uncaught exception handler cannot change the + * launcher's return code except by calling System.exit. + * + * Wait for all non-daemon threads to end, then destroy the VM. + * This will actually create a trivial new Java waiter thread + * named "DestroyJavaVM", but this will be seen as a different + * thread from the one that executed main, even though they are + * the same C thread. This allows mainThread.join() and + * mainThread.isAlive() to work as expected. + */ +#define LEAVE() \ + do { \ + if ((*vm)->DetachCurrentThread(vm) != JNI_OK) { \ + JLI_ReportErrorMessage(JVM_ERROR2); \ + ret = 1; \ + } \ + if (JNI_TRUE) { \ + (*vm)->DestroyJavaVM(vm); \ + return ret; \ + } \ + } while (JNI_FALSE) + +#define CHECK_EXCEPTION_NULL_LEAVE(CENL_exception) \ + do { \ + if ((*env)->ExceptionOccurred(env)) { \ + JLI_ReportExceptionDescription(env); \ + LEAVE(); \ + } \ + if ((CENL_exception) == NULL) { \ + JLI_ReportErrorMessage(JNI_ERROR); \ + LEAVE(); \ + } \ + } while (JNI_FALSE) + +#define CHECK_EXCEPTION_LEAVE(CEL_return_value) \ + do { \ + if ((*env)->ExceptionOccurred(env)) { \ + JLI_ReportExceptionDescription(env); \ + ret = (CEL_return_value); \ + LEAVE(); \ + } \ + } while (JNI_FALSE) + +int JNICALL +JavaMain(void * _args) +{ + JavaMainArgs *args = (JavaMainArgs *)_args; + int argc = args->argc; + char **argv = args->argv; + int mode = args->mode; + char *what = args->what; + InvocationFunctions ifn = args->ifn; + + JavaVM *vm = 0; + JNIEnv *env = 0; + jclass mainClass = NULL; + jclass appClass = NULL; // actual application class being launched + jmethodID mainID; + jobjectArray mainArgs; + int ret = 0; + jlong start, end; + + RegisterThread(); + + /* Initialize the virtual machine */ + start = CounterGet(); + if (!InitializeJVM(&vm, &env, &ifn)) { + JLI_ReportErrorMessage(JVM_ERROR1); + exit(1); + } + + if (showSettings != NULL) { + ShowSettings(env, showSettings); + CHECK_EXCEPTION_LEAVE(1); + } + + if (printVersion || showVersion) { + PrintJavaVersion(env, showVersion); + CHECK_EXCEPTION_LEAVE(0); + if (printVersion) { + LEAVE(); + } + } + + /* If the user specified neither a class name nor a JAR file */ + if (printXUsage || printUsage || what == 0 || mode == LM_UNKNOWN) { + PrintUsage(env, printXUsage); + CHECK_EXCEPTION_LEAVE(1); + LEAVE(); + } + + FreeKnownVMs(); /* after last possible PrintUsage() */ + + if (JLI_IsTraceLauncher()) { + end = CounterGet(); + JLI_TraceLauncher("%ld micro seconds to InitializeJVM\n", + (long)(jint)Counter2Micros(end-start)); + } + + /* At this stage, argc/argv have the application's arguments */ + if (JLI_IsTraceLauncher()){ + int i; + printf("%s is '%s'\n", launchModeNames[mode], what); + printf("App's argc is %d\n", argc); + for (i=0; i < argc; i++) { + printf(" argv[%2d] = '%s'\n", i, argv[i]); + } + } + + ret = 1; + + /* + * Get the application's main class. + * + * See bugid 5030265. The Main-Class name has already been parsed + * from the manifest, but not parsed properly for UTF-8 support. + * Hence the code here ignores the value previously extracted and + * uses the pre-existing code to reextract the value. This is + * possibly an end of release cycle expedient. However, it has + * also been discovered that passing some character sets through + * the environment has "strange" behavior on some variants of + * Windows. Hence, maybe the manifest parsing code local to the + * launcher should never be enhanced. + * + * Hence, future work should either: + * 1) Correct the local parsing code and verify that the + * Main-Class attribute gets properly passed through + * all environments, + * 2) Remove the vestages of maintaining main_class through + * the environment (and remove these comments). + * + * This method also correctly handles launching existing JavaFX + * applications that may or may not have a Main-Class manifest entry. + */ + mainClass = LoadMainClass(env, mode, what); + CHECK_EXCEPTION_NULL_LEAVE(mainClass); + /* + * In some cases when launching an application that needs a helper, e.g., a + * JavaFX application with no main method, the mainClass will not be the + * applications own main class but rather a helper class. To keep things + * consistent in the UI we need to track and report the application main class. + */ + appClass = GetApplicationClass(env); + NULL_CHECK_RETURN_VALUE(appClass, -1); + /* + * PostJVMInit uses the class name as the application name for GUI purposes, + * for example, on OSX this sets the application name in the menu bar for + * both SWT and JavaFX. So we'll pass the actual application class here + * instead of mainClass as that may be a launcher or helper class instead + * of the application class. + */ + PostJVMInit(env, appClass, vm); + CHECK_EXCEPTION_LEAVE(1); + /* + * The LoadMainClass not only loads the main class, it will also ensure + * that the main method's signature is correct, therefore further checking + * is not required. The main method is invoked here so that extraneous java + * stacks are not in the application stack trace. + */ + mainID = (*env)->GetStaticMethodID(env, mainClass, "main", + "([Ljava/lang/String;)V"); + CHECK_EXCEPTION_NULL_LEAVE(mainID); + + /* Build platform specific argument array */ + mainArgs = CreateApplicationArgs(env, argv, argc); + CHECK_EXCEPTION_NULL_LEAVE(mainArgs); + + /* Invoke main method. */ + (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); + + /* + * The launcher's exit code (in the absence of calls to + * System.exit) will be non-zero if main threw an exception. + */ + ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1; + LEAVE(); +} + +/* + * Checks the command line options to find which JVM type was + * specified. If no command line option was given for the JVM type, + * the default type is used. The environment variable + * JDK_ALTERNATE_VM and the command line option -XXaltjvm= are also + * checked as ways of specifying which JVM type to invoke. + */ +char * +CheckJvmType(int *pargc, char ***argv, jboolean speculative) { + int i, argi; + int argc; + char **newArgv; + int newArgvIdx = 0; + int isVMType; + int jvmidx = -1; + char *jvmtype = getenv("JDK_ALTERNATE_VM"); + + argc = *pargc; + + /* To make things simpler we always copy the argv array */ + newArgv = JLI_MemAlloc((argc + 1) * sizeof(char *)); + + /* The program name is always present */ + newArgv[newArgvIdx++] = (*argv)[0]; + + for (argi = 1; argi < argc; argi++) { + char *arg = (*argv)[argi]; + isVMType = 0; + + if (IsJavaArgs()) { + if (arg[0] != '-') { + newArgv[newArgvIdx++] = arg; + continue; + } + } else { + if (JLI_StrCmp(arg, "-classpath") == 0 || + JLI_StrCmp(arg, "-cp") == 0) { + newArgv[newArgvIdx++] = arg; + argi++; + if (argi < argc) { + newArgv[newArgvIdx++] = (*argv)[argi]; + } + continue; + } + if (arg[0] != '-') break; + } + + /* Did the user pass an explicit VM type? */ + i = KnownVMIndex(arg); + if (i >= 0) { + jvmtype = knownVMs[jvmidx = i].name + 1; /* skip the - */ + isVMType = 1; + *pargc = *pargc - 1; + } + + /* Did the user specify an "alternate" VM? */ + else if (JLI_StrCCmp(arg, "-XXaltjvm=") == 0 || JLI_StrCCmp(arg, "-J-XXaltjvm=") == 0) { + isVMType = 1; + jvmtype = arg+((arg[1]=='X')? 10 : 12); + jvmidx = -1; + } + + if (!isVMType) { + newArgv[newArgvIdx++] = arg; + } + } + + /* + * Finish copying the arguments if we aborted the above loop. + * NOTE that if we aborted via "break" then we did NOT copy the + * last argument above, and in addition argi will be less than + * argc. + */ + while (argi < argc) { + newArgv[newArgvIdx++] = (*argv)[argi]; + argi++; + } + + /* argv is null-terminated */ + newArgv[newArgvIdx] = 0; + + /* Copy back argv */ + *argv = newArgv; + *pargc = newArgvIdx; + + /* use the default VM type if not specified (no alias processing) */ + if (jvmtype == NULL) { + char* result = knownVMs[0].name+1; + /* Use a different VM type if we are on a server class machine? */ + if ((knownVMs[0].flag == VM_IF_SERVER_CLASS) && + (ServerClassMachine() == JNI_TRUE)) { + result = knownVMs[0].server_class+1; + } + JLI_TraceLauncher("Default VM: %s\n", result); + return result; + } + + /* if using an alternate VM, no alias processing */ + if (jvmidx < 0) + return jvmtype; + + /* Resolve aliases first */ + { + int loopCount = 0; + while (knownVMs[jvmidx].flag == VM_ALIASED_TO) { + int nextIdx = KnownVMIndex(knownVMs[jvmidx].alias); + + if (loopCount > knownVMsCount) { + if (!speculative) { + JLI_ReportErrorMessage(CFG_ERROR1); + exit(1); + } else { + return "ERROR"; + /* break; */ + } + } + + if (nextIdx < 0) { + if (!speculative) { + JLI_ReportErrorMessage(CFG_ERROR2, knownVMs[jvmidx].alias); + exit(1); + } else { + return "ERROR"; + } + } + jvmidx = nextIdx; + jvmtype = knownVMs[jvmidx].name+1; + loopCount++; + } + } + + switch (knownVMs[jvmidx].flag) { + case VM_WARN: + if (!speculative) { + JLI_ReportErrorMessage(CFG_WARN1, jvmtype, knownVMs[0].name + 1); + } + /* fall through */ + case VM_IGNORE: + jvmtype = knownVMs[jvmidx=0].name + 1; + /* fall through */ + case VM_KNOWN: + break; + case VM_ERROR: + if (!speculative) { + JLI_ReportErrorMessage(CFG_ERROR3, jvmtype); + exit(1); + } else { + return "ERROR"; + } + } + + return jvmtype; +} + +/* + * static void SetJvmEnvironment(int argc, char **argv); + * Is called just before the JVM is loaded. We can set env variables + * that are consumed by the JVM. This function is non-destructive, + * leaving the arg list intact. The first use is for the JVM flag + * -XX:NativeMemoryTracking=value. + */ +static void +SetJvmEnvironment(int argc, char **argv) { + + static const char* NMT_Env_Name = "NMT_LEVEL_"; + + int i; + for (i = 0; i < argc; i++) { + /* + * The following case checks for "-XX:NativeMemoryTracking=value". + * If value is non null, an environmental variable set to this value + * will be created to be used by the JVM. + * The argument is passed to the JVM, which will check validity. + * The JVM is responsible for removing the env variable. + */ + char *arg = argv[i]; + if (JLI_StrCCmp(arg, "-XX:NativeMemoryTracking=") == 0) { + int retval; + // get what follows this parameter, include "=" + size_t pnlen = JLI_StrLen("-XX:NativeMemoryTracking="); + if (JLI_StrLen(arg) > pnlen) { + char* value = arg + pnlen; + size_t pbuflen = pnlen + JLI_StrLen(value) + 10; // 10 max pid digits + + /* + * ensures that malloc successful + * DONT JLI_MemFree() pbuf. JLI_PutEnv() uses system call + * that could store the address. + */ + char * pbuf = (char*)JLI_MemAlloc(pbuflen); + + JLI_Snprintf(pbuf, pbuflen, "%s%d=%s", NMT_Env_Name, JLI_GetPid(), value); + retval = JLI_PutEnv(pbuf); + if (JLI_IsTraceLauncher()) { + char* envName; + char* envBuf; + + // ensures that malloc successful + envName = (char*)JLI_MemAlloc(pbuflen); + JLI_Snprintf(envName, pbuflen, "%s%d", NMT_Env_Name, JLI_GetPid()); + + printf("TRACER_MARKER: NativeMemoryTracking: env var is %s\n",envName); + printf("TRACER_MARKER: NativeMemoryTracking: putenv arg %s\n",pbuf); + envBuf = getenv(envName); + printf("TRACER_MARKER: NativeMemoryTracking: got value %s\n",envBuf); + free(envName); + } + + } + + } + + } +} + +/* copied from HotSpot function "atomll()" */ +static int +parse_size(const char *s, jlong *result) { + jlong n = 0; + int args_read = sscanf(s, jlong_format_specifier(), &n); + if (args_read != 1) { + return 0; + } + while (*s != '\0' && *s >= '0' && *s <= '9') { + s++; + } + // 4705540: illegal if more characters are found after the first non-digit + if (JLI_StrLen(s) > 1) { + return 0; + } + switch (*s) { + case 'T': case 't': + *result = n * GB * KB; + return 1; + case 'G': case 'g': + *result = n * GB; + return 1; + case 'M': case 'm': + *result = n * MB; + return 1; + case 'K': case 'k': + *result = n * KB; + return 1; + case '\0': + *result = n; + return 1; + default: + /* Create JVM with default stack and let VM handle malformed -Xss string*/ + return 0; + } +} + +/* + * Adds a new VM option with the given given name and value. + */ +void +AddOption(char *str, void *info) +{ + /* + * Expand options array if needed to accommodate at least one more + * VM option. + */ + if (numOptions >= maxOptions) { + if (options == 0) { + maxOptions = 4; + options = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption)); + } else { + JavaVMOption *tmp; + maxOptions *= 2; + tmp = JLI_MemAlloc(maxOptions * sizeof(JavaVMOption)); + memcpy(tmp, options, numOptions * sizeof(JavaVMOption)); + JLI_MemFree(options); + options = tmp; + } + } + options[numOptions].optionString = str; + options[numOptions++].extraInfo = info; + + if (JLI_StrCCmp(str, "-Xss") == 0) { + jlong tmp; + if (parse_size(str + 4, &tmp)) { + threadStackSize = tmp; + } + } + + if (JLI_StrCCmp(str, "-Xmx") == 0) { + jlong tmp; + if (parse_size(str + 4, &tmp)) { + maxHeapSize = tmp; + } + } + + if (JLI_StrCCmp(str, "-Xms") == 0) { + jlong tmp; + if (parse_size(str + 4, &tmp)) { + initialHeapSize = tmp; + } + } +} + +static void +SetClassPath(const char *s) +{ + char *def; + const char *orig = s; + static const char format[] = "-Djava.class.path=%s"; + /* + * usually we should not get a null pointer, but there are cases where + * we might just get one, in which case we simply ignore it, and let the + * caller deal with it + */ + if (s == NULL) + return; + s = JLI_WildcardExpandClasspath(s); + if (sizeof(format) - 2 + JLI_StrLen(s) < JLI_StrLen(s)) + // s is corrupted after wildcard expansion + return; + def = JLI_MemAlloc(sizeof(format) + - 2 /* strlen("%s") */ + + JLI_StrLen(s)); + sprintf(def, format, s); + AddOption(def, NULL); + if (s != orig) + JLI_MemFree((char *) s); +} + +/* + * The SelectVersion() routine ensures that an appropriate version of + * the JRE is running. The specification for the appropriate version + * is obtained from either the manifest of a jar file (preferred) or + * from command line options. + * The routine also parses splash screen command line options and + * passes on their values in private environment variables. + */ +static void +SelectVersion(int argc, char **argv, char **main_class) +{ + char *arg; + char **new_argv; + char **new_argp; + char *operand; + char *version = NULL; + char *jre = NULL; + int jarflag = 0; + int headlessflag = 0; + int restrict_search = -1; /* -1 implies not known */ + manifest_info info; + char env_entry[MAXNAMELEN + 24] = ENV_ENTRY "="; + char *splash_file_name = NULL; + char *splash_jar_name = NULL; + char *env_in; + int res; + + /* + * If the version has already been selected, set *main_class + * with the value passed through the environment (if any) and + * simply return. + */ + if ((env_in = getenv(ENV_ENTRY)) != NULL) { + if (*env_in != '\0') + *main_class = JLI_StringDup(env_in); + return; + } + + /* + * Scan through the arguments for options relevant to multiple JRE + * support. For reference, the command line syntax is defined as: + * + * SYNOPSIS + * java [options] class [argument...] + * + * java [options] -jar file.jar [argument...] + * + * As the scan is performed, make a copy of the argument list with + * the version specification options (new to 1.5) removed, so that + * a version less than 1.5 can be exec'd. + * + * Note that due to the syntax of the native Windows interface + * CreateProcess(), processing similar to the following exists in + * the Windows platform specific routine ExecJRE (in java_md.c). + * Changes here should be reproduced there. + */ + new_argv = JLI_MemAlloc((argc + 1) * sizeof(char*)); + new_argv[0] = argv[0]; + new_argp = &new_argv[1]; + argc--; + argv++; + while ((arg = *argv) != 0 && *arg == '-') { + if (JLI_StrCCmp(arg, "-version:") == 0) { + version = arg + 9; + } else if (JLI_StrCmp(arg, "-jre-restrict-search") == 0) { + restrict_search = 1; + } else if (JLI_StrCmp(arg, "-no-jre-restrict-search") == 0) { + restrict_search = 0; + } else { + if (JLI_StrCmp(arg, "-jar") == 0) + jarflag = 1; + /* deal with "unfortunate" classpath syntax */ + if ((JLI_StrCmp(arg, "-classpath") == 0 || JLI_StrCmp(arg, "-cp") == 0) && + (argc >= 2)) { + *new_argp++ = arg; + argc--; + argv++; + arg = *argv; + } + + /* + * Checking for headless toolkit option in the some way as AWT does: + * "true" means true and any other value means false + */ + if (JLI_StrCmp(arg, "-Djava.awt.headless=true") == 0) { + headlessflag = 1; + } else if (JLI_StrCCmp(arg, "-Djava.awt.headless=") == 0) { + headlessflag = 0; + } else if (JLI_StrCCmp(arg, "-splash:") == 0) { + splash_file_name = arg+8; + } + *new_argp++ = arg; + } + argc--; + argv++; + } + if (argc <= 0) { /* No operand? Possibly legit with -[full]version */ + operand = NULL; + } else { + argc--; + *new_argp++ = operand = *argv++; + } + while (argc-- > 0) /* Copy over [argument...] */ + *new_argp++ = *argv++; + *new_argp = NULL; + + /* + * If there is a jar file, read the manifest. If the jarfile can't be + * read, the manifest can't be read from the jar file, or the manifest + * is corrupt, issue the appropriate error messages and exit. + * + * Even if there isn't a jar file, construct a manifest_info structure + * containing the command line information. It's a convenient way to carry + * this data around. + */ + if (jarflag && operand) { + if ((res = JLI_ParseManifest(operand, &info)) != 0) { + if (res == -1) + JLI_ReportErrorMessage(JAR_ERROR2, operand); + else + JLI_ReportErrorMessage(JAR_ERROR3, operand); + exit(1); + } + + /* + * Command line splash screen option should have precedence + * over the manifest, so the manifest data is used only if + * splash_file_name has not been initialized above during command + * line parsing + */ + if (!headlessflag && !splash_file_name && info.splashscreen_image_file_name) { + splash_file_name = info.splashscreen_image_file_name; + splash_jar_name = operand; + } + } else { + info.manifest_version = NULL; + info.main_class = NULL; + info.jre_version = NULL; + info.jre_restrict_search = 0; + } + + /* + * Passing on splash screen info in environment variables + */ + if (splash_file_name && !headlessflag) { + char* splash_file_entry = JLI_MemAlloc(JLI_StrLen(SPLASH_FILE_ENV_ENTRY "=")+JLI_StrLen(splash_file_name)+1); + JLI_StrCpy(splash_file_entry, SPLASH_FILE_ENV_ENTRY "="); + JLI_StrCat(splash_file_entry, splash_file_name); + putenv(splash_file_entry); + } + if (splash_jar_name && !headlessflag) { + char* splash_jar_entry = JLI_MemAlloc(JLI_StrLen(SPLASH_JAR_ENV_ENTRY "=")+JLI_StrLen(splash_jar_name)+1); + JLI_StrCpy(splash_jar_entry, SPLASH_JAR_ENV_ENTRY "="); + JLI_StrCat(splash_jar_entry, splash_jar_name); + putenv(splash_jar_entry); + } + + /* + * The JRE-Version and JRE-Restrict-Search values (if any) from the + * manifest are overwritten by any specified on the command line. + */ + if (version != NULL) + info.jre_version = version; + if (restrict_search != -1) + info.jre_restrict_search = restrict_search; + + /* + * "Valid" returns (other than unrecoverable errors) follow. Set + * main_class as a side-effect of this routine. + */ + if (info.main_class != NULL) + *main_class = JLI_StringDup(info.main_class); + + /* + * If no version selection information is found either on the command + * line or in the manifest, simply return. + */ + if (info.jre_version == NULL) { + JLI_FreeManifest(); + JLI_MemFree(new_argv); + return; + } + + /* + * Check for correct syntax of the version specification (JSR 56). + */ + if (!JLI_ValidVersionString(info.jre_version)) { + JLI_ReportErrorMessage(SPC_ERROR1, info.jre_version); + exit(1); + } + + /* + * Find the appropriate JVM on the system. Just to be as forgiving as + * possible, if the standard algorithms don't locate an appropriate + * jre, check to see if the one running will satisfy the requirements. + * This can happen on systems which haven't been set-up for multiple + * JRE support. + */ + jre = LocateJRE(&info); + JLI_TraceLauncher("JRE-Version = %s, JRE-Restrict-Search = %s Selected = %s\n", + (info.jre_version?info.jre_version:"null"), + (info.jre_restrict_search?"true":"false"), (jre?jre:"null")); + + if (jre == NULL) { + if (JLI_AcceptableRelease(GetFullVersion(), info.jre_version)) { + JLI_FreeManifest(); + JLI_MemFree(new_argv); + return; + } else { + JLI_ReportErrorMessage(CFG_ERROR4, info.jre_version); + exit(1); + } + } + + /* + * If I'm not the chosen one, exec the chosen one. Returning from + * ExecJRE indicates that I am indeed the chosen one. + * + * The private environment variable _JAVA_VERSION_SET is used to + * prevent the chosen one from re-reading the manifest file and + * using the values found within to override the (potential) command + * line flags stripped from argv (because the target may not + * understand them). Passing the MainClass value is an optimization + * to avoid locating, expanding and parsing the manifest extra + * times. + */ + if (info.main_class != NULL) { + if (JLI_StrLen(info.main_class) <= MAXNAMELEN) { + (void)JLI_StrCat(env_entry, info.main_class); + } else { + JLI_ReportErrorMessage(CLS_ERROR5, MAXNAMELEN); + exit(1); + } + } + (void)putenv(env_entry); + ExecJRE(jre, new_argv); + JLI_FreeManifest(); + JLI_MemFree(new_argv); + return; +} + +/* + * Parses command line arguments. Returns JNI_FALSE if launcher + * should exit without starting vm, returns JNI_TRUE if vm needs + * to be started to process given options. *pret (the launcher + * process return value) is set to 0 for a normal exit. + */ +static jboolean +ParseArguments(int *pargc, char ***pargv, + int *pmode, char **pwhat, + int *pret, const char *jrepath) +{ + int argc = *pargc; + char **argv = *pargv; + int mode = LM_UNKNOWN; + char *arg; + + *pret = 0; + + while ((arg = *argv) != 0 && *arg == '-') { + argv++; --argc; + if (JLI_StrCmp(arg, "-classpath") == 0 || JLI_StrCmp(arg, "-cp") == 0) { + ARG_CHECK (argc, ARG_ERROR1, arg); + SetClassPath(*argv); + mode = LM_CLASS; + argv++; --argc; + } else if (JLI_StrCmp(arg, "-jar") == 0) { + ARG_CHECK (argc, ARG_ERROR2, arg); + mode = LM_JAR; + } else if (JLI_StrCmp(arg, "-help") == 0 || + JLI_StrCmp(arg, "-h") == 0 || + JLI_StrCmp(arg, "-?") == 0) { + printUsage = JNI_TRUE; + return JNI_TRUE; + } else if (JLI_StrCmp(arg, "-version") == 0) { + printVersion = JNI_TRUE; + return JNI_TRUE; + } else if (JLI_StrCmp(arg, "-showversion") == 0) { + showVersion = JNI_TRUE; + } else if (JLI_StrCmp(arg, "-X") == 0) { + printXUsage = JNI_TRUE; + return JNI_TRUE; +/* + * The following case checks for -XshowSettings OR -XshowSetting:SUBOPT. + * In the latter case, any SUBOPT value not recognized will default to "all" + */ + } else if (JLI_StrCmp(arg, "-XshowSettings") == 0 || + JLI_StrCCmp(arg, "-XshowSettings:") == 0) { + showSettings = arg; + } else if (JLI_StrCmp(arg, "-Xdiag") == 0) { + AddOption("-Dsun.java.launcher.diag=true", NULL); +/* + * The following case provide backward compatibility with old-style + * command line options. + */ + } else if (JLI_StrCmp(arg, "-fullversion") == 0) { + JLI_ReportMessage("%s full version \"%s\"", _launcher_name, GetFullVersion()); + return JNI_FALSE; + } else if (JLI_StrCmp(arg, "-verbosegc") == 0) { + AddOption("-verbose:gc", NULL); + } else if (JLI_StrCmp(arg, "-t") == 0) { + AddOption("-Xt", NULL); + } else if (JLI_StrCmp(arg, "-tm") == 0) { + AddOption("-Xtm", NULL); + } else if (JLI_StrCmp(arg, "-debug") == 0) { + AddOption("-Xdebug", NULL); + } else if (JLI_StrCmp(arg, "-noclassgc") == 0) { + AddOption("-Xnoclassgc", NULL); + } else if (JLI_StrCmp(arg, "-Xfuture") == 0) { + AddOption("-Xverify:all", NULL); + } else if (JLI_StrCmp(arg, "-verify") == 0) { + AddOption("-Xverify:all", NULL); + } else if (JLI_StrCmp(arg, "-verifyremote") == 0) { + AddOption("-Xverify:remote", NULL); + } else if (JLI_StrCmp(arg, "-noverify") == 0) { + AddOption("-Xverify:none", NULL); + } else if (JLI_StrCCmp(arg, "-prof") == 0) { + char *p = arg + 5; + char *tmp = JLI_MemAlloc(JLI_StrLen(arg) + 50); + if (*p) { + sprintf(tmp, "-Xrunhprof:cpu=old,file=%s", p + 1); + } else { + sprintf(tmp, "-Xrunhprof:cpu=old,file=java.prof"); + } + AddOption(tmp, NULL); + } else if (JLI_StrCCmp(arg, "-ss") == 0 || + JLI_StrCCmp(arg, "-oss") == 0 || + JLI_StrCCmp(arg, "-ms") == 0 || + JLI_StrCCmp(arg, "-mx") == 0) { + char *tmp = JLI_MemAlloc(JLI_StrLen(arg) + 6); + sprintf(tmp, "-X%s", arg + 1); /* skip '-' */ + AddOption(tmp, NULL); + } else if (JLI_StrCmp(arg, "-checksource") == 0 || + JLI_StrCmp(arg, "-cs") == 0 || + JLI_StrCmp(arg, "-noasyncgc") == 0) { + /* No longer supported */ + JLI_ReportErrorMessage(ARG_WARN, arg); + } else if (JLI_StrCCmp(arg, "-version:") == 0 || + JLI_StrCmp(arg, "-no-jre-restrict-search") == 0 || + JLI_StrCmp(arg, "-jre-restrict-search") == 0 || + JLI_StrCCmp(arg, "-splash:") == 0) { + ; /* Ignore machine independent options already handled */ + } else if (ProcessPlatformOption(arg)) { + ; /* Processing of platform dependent options */ + } else if (RemovableOption(arg)) { + ; /* Do not pass option to vm. */ + } else { + AddOption(arg, NULL); + } + } + + if (--argc >= 0) { + *pwhat = *argv++; + } + + if (*pwhat == NULL) { + *pret = 1; + } else if (mode == LM_UNKNOWN) { + /* default to LM_CLASS if -jar and -cp option are + * not specified */ + mode = LM_CLASS; + } + + if (argc >= 0) { + *pargc = argc; + *pargv = argv; + } + + *pmode = mode; + + return JNI_TRUE; +} + +/* + * Initializes the Java Virtual Machine. Also frees options array when + * finished. + */ +static jboolean +InitializeJVM(JavaVM **pvm, JNIEnv **penv, InvocationFunctions *ifn) +{ + JavaVMInitArgs args; + jint r; + + memset(&args, 0, sizeof(args)); + args.version = JNI_VERSION_1_2; + args.nOptions = numOptions; + args.options = options; + args.ignoreUnrecognized = JNI_FALSE; + + if (JLI_IsTraceLauncher()) { + int i = 0; + printf("JavaVM args:\n "); + printf("version 0x%08lx, ", (long)args.version); + printf("ignoreUnrecognized is %s, ", + args.ignoreUnrecognized ? "JNI_TRUE" : "JNI_FALSE"); + printf("nOptions is %ld\n", (long)args.nOptions); + for (i = 0; i < numOptions; i++) + printf(" option[%2d] = '%s'\n", + i, args.options[i].optionString); + } + + r = ifn->CreateJavaVM(pvm, (void **)penv, &args); + JLI_MemFree(options); + return r == JNI_OK; +} + +static jclass helperClass = NULL; + +jclass +GetLauncherHelperClass(JNIEnv *env) +{ + if (helperClass == NULL) { + NULL_CHECK0(helperClass = FindBootStrapClass(env, + "sun/launcher/LauncherHelper")); + } + return helperClass; +} + +static jmethodID makePlatformStringMID = NULL; +/* + * Returns a new Java string object for the specified platform string. + */ +static jstring +NewPlatformString(JNIEnv *env, char *s) +{ + int len = (int)JLI_StrLen(s); + jbyteArray ary; + jclass cls = GetLauncherHelperClass(env); + NULL_CHECK0(cls); + if (s == NULL) + return 0; + + ary = (*env)->NewByteArray(env, len); + if (ary != 0) { + jstring str = 0; + (*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s); + if (!(*env)->ExceptionOccurred(env)) { + if (makePlatformStringMID == NULL) { + CHECK_JNI_RETURN_0( + makePlatformStringMID = (*env)->GetStaticMethodID(env, + cls, "makePlatformString", "(Z[B)Ljava/lang/String;")); + } + CHECK_JNI_RETURN_0( + str = (*env)->CallStaticObjectMethod(env, cls, + makePlatformStringMID, USE_STDERR, ary)); + (*env)->DeleteLocalRef(env, ary); + return str; + } + } + return 0; +} + +/* + * Returns a new array of Java string objects for the specified + * array of platform strings. + */ +jobjectArray +NewPlatformStringArray(JNIEnv *env, char **strv, int strc) +{ + jarray cls; + jarray ary; + int i; + + NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String")); + NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0)); + for (i = 0; i < strc; i++) { + jstring str = NewPlatformString(env, *strv++); + NULL_CHECK0(str); + (*env)->SetObjectArrayElement(env, ary, i, str); + (*env)->DeleteLocalRef(env, str); + } + return ary; +} + +/* + * Loads a class and verifies that the main class is present and it is ok to + * call it for more details refer to the java implementation. + */ +static jclass +LoadMainClass(JNIEnv *env, int mode, char *name) +{ + jmethodID mid; + jstring str; + jobject result; + jlong start, end; + jclass cls = GetLauncherHelperClass(env); + NULL_CHECK0(cls); + if (JLI_IsTraceLauncher()) { + start = CounterGet(); + } + NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, + "checkAndLoadMain", + "(ZILjava/lang/String;)Ljava/lang/Class;")); + + str = NewPlatformString(env, name); + CHECK_JNI_RETURN_0( + result = (*env)->CallStaticObjectMethod( + env, cls, mid, USE_STDERR, mode, str)); + + if (JLI_IsTraceLauncher()) { + end = CounterGet(); + printf("%ld micro seconds to load main class\n", + (long)(jint)Counter2Micros(end-start)); + printf("----%s----\n", JLDEBUG_ENV_ENTRY); + } + + return (jclass)result; +} + +static jclass +GetApplicationClass(JNIEnv *env) +{ + jmethodID mid; + jobject result; + jclass cls = GetLauncherHelperClass(env); + NULL_CHECK0(cls); + NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, + "getApplicationClass", + "()Ljava/lang/Class;")); + + return (*env)->CallStaticObjectMethod(env, cls, mid); +} + +/* + * For tools, convert command line args thus: + * javac -cp foo:foo/"*" -J-ms32m ... + * java -ms32m -cp JLI_WildcardExpandClasspath(foo:foo/"*") ... + * + * Takes 4 parameters, and returns the populated arguments + */ +static void +TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv) +{ + int argc = *pargc; + char **argv = *pargv; + int nargc = argc + jargc; + char **nargv = JLI_MemAlloc((nargc + 1) * sizeof(char *)); + int i; + + *pargc = nargc; + *pargv = nargv; + + /* Copy the VM arguments (i.e. prefixed with -J) */ + for (i = 0; i < jargc; i++) { + const char *arg = jargv[i]; + if (arg[0] == '-' && arg[1] == 'J') { + *nargv++ = ((arg + 2) == NULL) ? NULL : JLI_StringDup(arg + 2); + } + } + + for (i = 0; i < argc; i++) { + char *arg = argv[i]; + if (arg[0] == '-' && arg[1] == 'J') { + if (arg[2] == '\0') { + JLI_ReportErrorMessage(ARG_ERROR3); + exit(1); + } + *nargv++ = arg + 2; + } + } + + /* Copy the rest of the arguments */ + for (i = 0; i < jargc ; i++) { + const char *arg = jargv[i]; + if (arg[0] != '-' || arg[1] != 'J') { + *nargv++ = (arg == NULL) ? NULL : JLI_StringDup(arg); + } + } + for (i = 0; i < argc; i++) { + char *arg = argv[i]; + if (arg[0] == '-') { + if (arg[1] == 'J') + continue; + if (IsWildCardEnabled() && arg[1] == 'c' + && (JLI_StrCmp(arg, "-cp") == 0 || + JLI_StrCmp(arg, "-classpath") == 0) + && i < argc - 1) { + *nargv++ = arg; + *nargv++ = (char *) JLI_WildcardExpandClasspath(argv[i+1]); + i++; + continue; + } + } + *nargv++ = arg; + } + *nargv = 0; +} + +/* + * For our tools, we try to add 3 VM options: + * -Denv.class.path= + * -Dapplication.home= + * -Djava.class.path= + * is the user's setting of CLASSPATH -- for instance the user + * tells javac where to find binary classes through this environment + * variable. Notice that users will be able to compile against our + * tools classes (sun.tools.javac.Main) only if they explicitly add + * tools.jar to CLASSPATH. + * is the directory where the application is installed. + * is the classpath to where our apps' classfiles are. + */ +static jboolean +AddApplicationOptions(int cpathc, const char **cpathv) +{ + char *envcp, *appcp, *apphome; + char home[MAXPATHLEN]; /* application home */ + char separator[] = { PATH_SEPARATOR, '\0' }; + int size, i; + + { + const char *s = getenv("CLASSPATH"); + if (s) { + s = (char *) JLI_WildcardExpandClasspath(s); + /* 40 for -Denv.class.path= */ + if (JLI_StrLen(s) + 40 > JLI_StrLen(s)) { // Safeguard from overflow + envcp = (char *)JLI_MemAlloc(JLI_StrLen(s) + 40); + sprintf(envcp, "-Denv.class.path=%s", s); + AddOption(envcp, NULL); + } + } + } + + if (!GetApplicationHome(home, sizeof(home))) { + JLI_ReportErrorMessage(CFG_ERROR5); + return JNI_FALSE; + } + + /* 40 for '-Dapplication.home=' */ + apphome = (char *)JLI_MemAlloc(JLI_StrLen(home) + 40); + sprintf(apphome, "-Dapplication.home=%s", home); + AddOption(apphome, NULL); + + /* How big is the application's classpath? */ + size = 40; /* 40: "-Djava.class.path=" */ + for (i = 0; i < cpathc; i++) { + size += (int)JLI_StrLen(home) + (int)JLI_StrLen(cpathv[i]) + 1; /* 1: separator */ + } + appcp = (char *)JLI_MemAlloc(size + 1); + JLI_StrCpy(appcp, "-Djava.class.path="); + for (i = 0; i < cpathc; i++) { + JLI_StrCat(appcp, home); /* c:\program files\myapp */ + JLI_StrCat(appcp, cpathv[i]); /* \lib\myapp.jar */ + JLI_StrCat(appcp, separator); /* ; */ + } + appcp[JLI_StrLen(appcp)-1] = '\0'; /* remove trailing path separator */ + AddOption(appcp, NULL); + return JNI_TRUE; +} + +/* + * inject the -Dsun.java.command pseudo property into the args structure + * this pseudo property is used in the HotSpot VM to expose the + * Java class name and arguments to the main method to the VM. The + * HotSpot VM uses this pseudo property to store the Java class name + * (or jar file name) and the arguments to the class's main method + * to the instrumentation memory region. The sun.java.command pseudo + * property is not exported by HotSpot to the Java layer. + */ +void +SetJavaCommandLineProp(char *what, int argc, char **argv) +{ + + int i = 0; + size_t len = 0; + char* javaCommand = NULL; + char* dashDstr = "-Dsun.java.command="; + + if (what == NULL) { + /* unexpected, one of these should be set. just return without + * setting the property + */ + return; + } + + /* determine the amount of memory to allocate assuming + * the individual components will be space separated + */ + len = JLI_StrLen(what); + for (i = 0; i < argc; i++) { + len += JLI_StrLen(argv[i]) + 1; + } + + /* allocate the memory */ + javaCommand = (char*) JLI_MemAlloc(len + JLI_StrLen(dashDstr) + 1); + + /* build the -D string */ + *javaCommand = '\0'; + JLI_StrCat(javaCommand, dashDstr); + JLI_StrCat(javaCommand, what); + + for (i = 0; i < argc; i++) { + /* the components of the string are space separated. In + * the case of embedded white space, the relationship of + * the white space separated components to their true + * positional arguments will be ambiguous. This issue may + * be addressed in a future release. + */ + JLI_StrCat(javaCommand, " "); + JLI_StrCat(javaCommand, argv[i]); + } + + AddOption(javaCommand, NULL); +} + +/* + * JVM would like to know if it's created by a standard Sun launcher, or by + * user native application, the following property indicates the former. + */ +void +SetJavaLauncherProp() { + AddOption("-Dsun.java.launcher=SUN_STANDARD", NULL); +} + +/* + * Prints the version information from the java.version and other properties. + */ +static void +PrintJavaVersion(JNIEnv *env, jboolean extraLF) +{ + jclass ver; + jmethodID print; + + NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version")); + NULL_CHECK(print = (*env)->GetStaticMethodID(env, + ver, + (extraLF == JNI_TRUE) ? "println" : "print", + "()V" + ) + ); + + (*env)->CallStaticVoidMethod(env, ver, print); +} + +/* + * Prints all the Java settings, see the java implementation for more details. + */ +static void +ShowSettings(JNIEnv *env, char *optString) +{ + jmethodID showSettingsID; + jstring joptString; + jclass cls = GetLauncherHelperClass(env); + NULL_CHECK(cls); + NULL_CHECK(showSettingsID = (*env)->GetStaticMethodID(env, cls, + "showSettings", "(ZLjava/lang/String;JJJZ)V")); + joptString = (*env)->NewStringUTF(env, optString); + (*env)->CallStaticVoidMethod(env, cls, showSettingsID, + USE_STDERR, + joptString, + (jlong)initialHeapSize, + (jlong)maxHeapSize, + (jlong)threadStackSize, + ServerClassMachine()); +} + +/* + * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java + */ +static void +PrintUsage(JNIEnv* env, jboolean doXUsage) +{ + jmethodID initHelp, vmSelect, vmSynonym, vmErgo, printHelp, printXUsageMessage; + jstring jprogname, vm1, vm2; + int i; + jclass cls = GetLauncherHelperClass(env); + NULL_CHECK(cls); + if (doXUsage) { + NULL_CHECK(printXUsageMessage = (*env)->GetStaticMethodID(env, cls, + "printXUsageMessage", "(Z)V")); + (*env)->CallStaticVoidMethod(env, cls, printXUsageMessage, USE_STDERR); + } else { + NULL_CHECK(initHelp = (*env)->GetStaticMethodID(env, cls, + "initHelpMessage", "(Ljava/lang/String;)V")); + + NULL_CHECK(vmSelect = (*env)->GetStaticMethodID(env, cls, "appendVmSelectMessage", + "(Ljava/lang/String;Ljava/lang/String;)V")); + + NULL_CHECK(vmSynonym = (*env)->GetStaticMethodID(env, cls, + "appendVmSynonymMessage", + "(Ljava/lang/String;Ljava/lang/String;)V")); + NULL_CHECK(vmErgo = (*env)->GetStaticMethodID(env, cls, + "appendVmErgoMessage", "(ZLjava/lang/String;)V")); + + NULL_CHECK(printHelp = (*env)->GetStaticMethodID(env, cls, + "printHelpMessage", "(Z)V")); + + jprogname = (*env)->NewStringUTF(env, _program_name); + + /* Initialize the usage message with the usual preamble */ + (*env)->CallStaticVoidMethod(env, cls, initHelp, jprogname); + + + /* Assemble the other variant part of the usage */ + if ((knownVMs[0].flag == VM_KNOWN) || + (knownVMs[0].flag == VM_IF_SERVER_CLASS)) { + vm1 = (*env)->NewStringUTF(env, knownVMs[0].name); + vm2 = (*env)->NewStringUTF(env, knownVMs[0].name+1); + (*env)->CallStaticVoidMethod(env, cls, vmSelect, vm1, vm2); + } + for (i=1; iNewStringUTF(env, knownVMs[i].name); + vm2 = (*env)->NewStringUTF(env, knownVMs[i].name+1); + (*env)->CallStaticVoidMethod(env, cls, vmSelect, vm1, vm2); + } + } + for (i=1; iNewStringUTF(env, knownVMs[i].name); + vm2 = (*env)->NewStringUTF(env, knownVMs[i].alias+1); + (*env)->CallStaticVoidMethod(env, cls, vmSynonym, vm1, vm2); + } + } + + /* The first known VM is the default */ + { + jboolean isServerClassMachine = ServerClassMachine(); + + const char* defaultVM = knownVMs[0].name+1; + if ((knownVMs[0].flag == VM_IF_SERVER_CLASS) && isServerClassMachine) { + defaultVM = knownVMs[0].server_class+1; + } + + vm1 = (*env)->NewStringUTF(env, defaultVM); + (*env)->CallStaticVoidMethod(env, cls, vmErgo, isServerClassMachine, vm1); + } + + /* Complete the usage message and print to stderr*/ + (*env)->CallStaticVoidMethod(env, cls, printHelp, USE_STDERR); + } + return; +} + +/* + * Read the jvm.cfg file and fill the knownJVMs[] array. + * + * The functionality of the jvm.cfg file is subject to change without + * notice and the mechanism will be removed in the future. + * + * The lexical structure of the jvm.cfg file is as follows: + * + * jvmcfg := { vmLine } + * vmLine := knownLine + * | aliasLine + * | warnLine + * | ignoreLine + * | errorLine + * | predicateLine + * | commentLine + * knownLine := flag "KNOWN" EOL + * warnLine := flag "WARN" EOL + * ignoreLine := flag "IGNORE" EOL + * errorLine := flag "ERROR" EOL + * aliasLine := flag "ALIASED_TO" flag EOL + * predicateLine := flag "IF_SERVER_CLASS" flag EOL + * commentLine := "#" text EOL + * flag := "-" identifier + * + * The semantics are that when someone specifies a flag on the command line: + * - if the flag appears on a knownLine, then the identifier is used as + * the name of the directory holding the JVM library (the name of the JVM). + * - if the flag appears as the first flag on an aliasLine, the identifier + * of the second flag is used as the name of the JVM. + * - if the flag appears on a warnLine, the identifier is used as the + * name of the JVM, but a warning is generated. + * - if the flag appears on an ignoreLine, the identifier is recognized as the + * name of a JVM, but the identifier is ignored and the default vm used + * - if the flag appears on an errorLine, an error is generated. + * - if the flag appears as the first flag on a predicateLine, and + * the machine on which you are running passes the predicate indicated, + * then the identifier of the second flag is used as the name of the JVM, + * otherwise the identifier of the first flag is used as the name of the JVM. + * If no flag is given on the command line, the first vmLine of the jvm.cfg + * file determines the name of the JVM. + * PredicateLines are only interpreted on first vmLine of a jvm.cfg file, + * since they only make sense if someone hasn't specified the name of the + * JVM on the command line. + * + * The intent of the jvm.cfg file is to allow several JVM libraries to + * be installed in different subdirectories of a single JRE installation, + * for space-savings and convenience in testing. + * The intent is explicitly not to provide a full aliasing or predicate + * mechanism. + */ +jint +ReadKnownVMs(const char *jvmCfgName, jboolean speculative) +{ + FILE *jvmCfg; + char line[MAXPATHLEN+20]; + int cnt = 0; + int lineno = 0; + jlong start, end; + int vmType; + char *tmpPtr; + char *altVMName = NULL; + char *serverClassVMName = NULL; + static char *whiteSpace = " \t"; + if (JLI_IsTraceLauncher()) { + start = CounterGet(); + } + + jvmCfg = fopen(jvmCfgName, "r"); + if (jvmCfg == NULL) { + if (!speculative) { + JLI_ReportErrorMessage(CFG_ERROR6, jvmCfgName); + exit(1); + } else { + return -1; + } + } + while (fgets(line, sizeof(line), jvmCfg) != NULL) { + vmType = VM_UNKNOWN; + lineno++; + if (line[0] == '#') + continue; + if (line[0] != '-') { + JLI_ReportErrorMessage(CFG_WARN2, lineno, jvmCfgName); + } + if (cnt >= knownVMsLimit) { + GrowKnownVMs(cnt); + } + line[JLI_StrLen(line)-1] = '\0'; /* remove trailing newline */ + tmpPtr = line + JLI_StrCSpn(line, whiteSpace); + if (*tmpPtr == 0) { + JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); + } else { + /* Null-terminate this string for JLI_StringDup below */ + *tmpPtr++ = 0; + tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace); + if (*tmpPtr == 0) { + JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); + } else { + if (!JLI_StrCCmp(tmpPtr, "KNOWN")) { + vmType = VM_KNOWN; + } else if (!JLI_StrCCmp(tmpPtr, "ALIASED_TO")) { + tmpPtr += JLI_StrCSpn(tmpPtr, whiteSpace); + if (*tmpPtr != 0) { + tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace); + } + if (*tmpPtr == 0) { + JLI_ReportErrorMessage(CFG_WARN3, lineno, jvmCfgName); + } else { + /* Null terminate altVMName */ + altVMName = tmpPtr; + tmpPtr += JLI_StrCSpn(tmpPtr, whiteSpace); + *tmpPtr = 0; + vmType = VM_ALIASED_TO; + } + } else if (!JLI_StrCCmp(tmpPtr, "WARN")) { + vmType = VM_WARN; + } else if (!JLI_StrCCmp(tmpPtr, "IGNORE")) { + vmType = VM_IGNORE; + } else if (!JLI_StrCCmp(tmpPtr, "ERROR")) { + vmType = VM_ERROR; + } else if (!JLI_StrCCmp(tmpPtr, "IF_SERVER_CLASS")) { + tmpPtr += JLI_StrCSpn(tmpPtr, whiteSpace); + if (*tmpPtr != 0) { + tmpPtr += JLI_StrSpn(tmpPtr, whiteSpace); + } + if (*tmpPtr == 0) { + JLI_ReportErrorMessage(CFG_WARN4, lineno, jvmCfgName); + } else { + /* Null terminate server class VM name */ + serverClassVMName = tmpPtr; + tmpPtr += JLI_StrCSpn(tmpPtr, whiteSpace); + *tmpPtr = 0; + vmType = VM_IF_SERVER_CLASS; + } + } else { + JLI_ReportErrorMessage(CFG_WARN5, lineno, &jvmCfgName[0]); + vmType = VM_KNOWN; + } + } + } + + JLI_TraceLauncher("jvm.cfg[%d] = ->%s<-\n", cnt, line); + if (vmType != VM_UNKNOWN) { + knownVMs[cnt].name = JLI_StringDup(line); + knownVMs[cnt].flag = vmType; + switch (vmType) { + default: + break; + case VM_ALIASED_TO: + knownVMs[cnt].alias = JLI_StringDup(altVMName); + JLI_TraceLauncher(" name: %s vmType: %s alias: %s\n", + knownVMs[cnt].name, "VM_ALIASED_TO", knownVMs[cnt].alias); + break; + case VM_IF_SERVER_CLASS: + knownVMs[cnt].server_class = JLI_StringDup(serverClassVMName); + JLI_TraceLauncher(" name: %s vmType: %s server_class: %s\n", + knownVMs[cnt].name, "VM_IF_SERVER_CLASS", knownVMs[cnt].server_class); + break; + } + cnt++; + } + } + fclose(jvmCfg); + knownVMsCount = cnt; + + if (JLI_IsTraceLauncher()) { + end = CounterGet(); + printf("%ld micro seconds to parse jvm.cfg\n", + (long)(jint)Counter2Micros(end-start)); + } + + return cnt; +} + + +static void +GrowKnownVMs(int minimum) +{ + struct vmdesc* newKnownVMs; + int newMax; + + newMax = (knownVMsLimit == 0 ? INIT_MAX_KNOWN_VMS : (2 * knownVMsLimit)); + if (newMax <= minimum) { + newMax = minimum; + } + newKnownVMs = (struct vmdesc*) JLI_MemAlloc(newMax * sizeof(struct vmdesc)); + if (knownVMs != NULL) { + memcpy(newKnownVMs, knownVMs, knownVMsLimit * sizeof(struct vmdesc)); + } + JLI_MemFree(knownVMs); + knownVMs = newKnownVMs; + knownVMsLimit = newMax; +} + + +/* Returns index of VM or -1 if not found */ +static int +KnownVMIndex(const char* name) +{ + int i; + if (JLI_StrCCmp(name, "-J") == 0) name += 2; + for (i = 0; i < knownVMsCount; i++) { + if (!JLI_StrCmp(name, knownVMs[i].name)) { + return i; + } + } + return -1; +} + +static void +FreeKnownVMs() +{ + int i; + for (i = 0; i < knownVMsCount; i++) { + JLI_MemFree(knownVMs[i].name); + knownVMs[i].name = NULL; + } + JLI_MemFree(knownVMs); +} + +/* + * Displays the splash screen according to the jar file name + * and image file names stored in environment variables + */ +void +ShowSplashScreen() +{ + const char *jar_name = getenv(SPLASH_JAR_ENV_ENTRY); + const char *file_name = getenv(SPLASH_FILE_ENV_ENTRY); + int data_size; + void *image_data = NULL; + float scale_factor = 1; + char *scaled_splash_name = NULL; + + if (file_name == NULL){ + return; + } + + scaled_splash_name = DoSplashGetScaledImageName( + jar_name, file_name, &scale_factor); + if (jar_name) { + + if (scaled_splash_name) { + image_data = JLI_JarUnpackFile( + jar_name, scaled_splash_name, &data_size); + } + + if (!image_data) { + scale_factor = 1; + image_data = JLI_JarUnpackFile( + jar_name, file_name, &data_size); + } + if (image_data) { + DoSplashInit(); + DoSplashSetScaleFactor(scale_factor); + DoSplashLoadMemory(image_data, data_size); + JLI_MemFree(image_data); + } + } else { + DoSplashInit(); + if (scaled_splash_name) { + DoSplashSetScaleFactor(scale_factor); + DoSplashLoadFile(scaled_splash_name); + } else { + DoSplashLoadFile(file_name); + } + } + + if (scaled_splash_name) { + JLI_MemFree(scaled_splash_name); + } + + DoSplashSetFileJarName(file_name, jar_name); + + /* + * Done with all command line processing and potential re-execs so + * clean up the environment. + */ + (void)UnsetEnv(ENV_ENTRY); + (void)UnsetEnv(SPLASH_FILE_ENV_ENTRY); + (void)UnsetEnv(SPLASH_JAR_ENV_ENTRY); + + JLI_MemFree(splash_jar_entry); + JLI_MemFree(splash_file_entry); + +} + +const char* +GetDotVersion() +{ + return _dVersion; +} + +const char* +GetFullVersion() +{ + return _fVersion; +} + +const char* +GetProgramName() +{ + return _program_name; +} + +const char* +GetLauncherName() +{ + return _launcher_name; +} + +jint +GetErgoPolicy() +{ + return _ergo_policy; +} + +jboolean +IsJavaArgs() +{ + return _is_java_args; +} + +static jboolean +IsWildCardEnabled() +{ + return _wc_enabled; +} + +int +ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize, + int argc, char **argv, + int mode, char *what, int ret) +{ + + /* + * If user doesn't specify stack size, check if VM has a preference. + * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will + * return its default stack size through the init args structure. + */ + if (threadStackSize == 0) { + struct JDK1_1InitArgs args1_1; + memset((void*)&args1_1, 0, sizeof(args1_1)); + args1_1.version = JNI_VERSION_1_1; + ifn->GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */ + if (args1_1.javaStackSize > 0) { + threadStackSize = args1_1.javaStackSize; + } + } + + { /* Create a new thread to create JVM and invoke main method */ + JavaMainArgs args; + int rslt; + + args.argc = argc; + args.argv = argv; + args.mode = mode; + args.what = what; + args.ifn = *ifn; + + rslt = ContinueInNewThread0(JavaMain, threadStackSize, (void*)&args); + /* If the caller has deemed there is an error we + * simply return that, otherwise we return the value of + * the callee + */ + return (ret != 0) ? ret : rslt; + } +} + +static void +DumpState() +{ + if (!JLI_IsTraceLauncher()) return ; + printf("Launcher state:\n"); + printf("\tdebug:%s\n", (JLI_IsTraceLauncher() == JNI_TRUE) ? "on" : "off"); + printf("\tjavargs:%s\n", (_is_java_args == JNI_TRUE) ? "on" : "off"); + printf("\tprogram name:%s\n", GetProgramName()); + printf("\tlauncher name:%s\n", GetLauncherName()); + printf("\tjavaw:%s\n", (IsJavaw() == JNI_TRUE) ? "on" : "off"); + printf("\tfullversion:%s\n", GetFullVersion()); + printf("\tdotversion:%s\n", GetDotVersion()); + printf("\tergo_policy:"); + switch(GetErgoPolicy()) { + case NEVER_SERVER_CLASS: + printf("NEVER_ACT_AS_A_SERVER_CLASS_MACHINE\n"); + break; + case ALWAYS_SERVER_CLASS: + printf("ALWAYS_ACT_AS_A_SERVER_CLASS_MACHINE\n"); + break; + default: + printf("DEFAULT_ERGONOMICS_POLICY\n"); + } +} + +/* + * Return JNI_TRUE for an option string that has no effect but should + * _not_ be passed on to the vm; return JNI_FALSE otherwise. On + * Solaris SPARC, this screening needs to be done if: + * -d32 or -d64 is passed to a binary with an unmatched data model + * (the exec in CreateExecutionEnvironment removes -d options and points the + * exec to the proper binary). In the case of when the data model and the + * requested version is matched, an exec would not occur, and these options + * were erroneously passed to the vm. + */ +jboolean +RemovableOption(char * option) +{ + /* + * Unconditionally remove both -d32 and -d64 options since only + * the last such options has an effect; e.g. + * java -d32 -d64 -d32 -version + * is equivalent to + * java -d32 -version + */ + + if( (JLI_StrCCmp(option, "-d32") == 0 ) || + (JLI_StrCCmp(option, "-d64") == 0 ) ) + return JNI_TRUE; + else + return JNI_FALSE; +} + +/* + * A utility procedure to always print to stderr + */ +void +JLI_ReportMessage(const char* fmt, ...) +{ + va_list vl; + va_start(vl, fmt); + vfprintf(stderr, fmt, vl); + fprintf(stderr, "\n"); + va_end(vl); +} diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java.h new file mode 100644 index 0000000..1f9f300 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java.h @@ -0,0 +1,309 @@ +/* + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _JAVA_H_ +#define _JAVA_H_ + +#include +#include +#include +#include + +#include +#include + +/* + * Get system specific defines. + */ +#include "emessages.h" +#include "java_md.h" +#include "jli_util.h" + +#include "manifest_info.h" +#include "version_comp.h" +#include "wildcard.h" +#include "splashscreen.h" + +# define KB (1024UL) +# define MB (1024UL * KB) +# define GB (1024UL * MB) + +#define CURRENT_DATA_MODEL (CHAR_BIT * sizeof(void*)) + +/* + * The following environment variable is used to influence the behavior + * of the jre exec'd through the SelectVersion routine. The command line + * options which specify the version are not passed to the exec'd version, + * because that jre may be an older version which wouldn't recognize them. + * This environment variable is known to this (and later) version and serves + * to suppress the version selection code. This is not only for efficiency, + * but also for correctness, since any command line options have been + * removed which would cause any value found in the manifest to be used. + * This would be incorrect because the command line options are defined + * to take precedence. + * + * The value associated with this environment variable is the MainClass + * name from within the executable jar file (if any). This is strictly a + * performance enhancement to avoid re-reading the jar file manifest. + * + */ +#define ENV_ENTRY "_JAVA_VERSION_SET" + +#define SPLASH_FILE_ENV_ENTRY "_JAVA_SPLASH_FILE" +#define SPLASH_JAR_ENV_ENTRY "_JAVA_SPLASH_JAR" + +/* + * Pointers to the needed JNI invocation API, initialized by LoadJavaVM. + */ +typedef jint (JNICALL *CreateJavaVM_t)(JavaVM **pvm, void **env, void *args); +typedef jint (JNICALL *GetDefaultJavaVMInitArgs_t)(void *args); +typedef jint (JNICALL *GetCreatedJavaVMs_t)(JavaVM **vmBuf, jsize bufLen, jsize *nVMs); + +typedef struct { + CreateJavaVM_t CreateJavaVM; + GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs; + GetCreatedJavaVMs_t GetCreatedJavaVMs; +} InvocationFunctions; + +int +JLI_Launch(int argc, char ** argv, /* main argc, argc */ + int jargc, const char** jargv, /* java args */ + int appclassc, const char** appclassv, /* app classpath */ + const char* fullversion, /* full version defined */ + const char* dotversion, /* dot version defined */ + const char* pname, /* program name */ + const char* lname, /* launcher name */ + jboolean javaargs, /* JAVA_ARGS */ + jboolean cpwildcard, /* classpath wildcard */ + jboolean javaw, /* windows-only javaw */ + jint ergo_class /* ergnomics policy */ +); + +/* + * Prototypes for launcher functions in the system specific java_md.c. + */ + +jboolean +LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn); + +void +GetXUsagePath(char *buf, jint bufsize); + +jboolean +GetApplicationHome(char *buf, jint bufsize); + +#define GetArch() GetArchPath(CURRENT_DATA_MODEL) + +/* + * Different platforms will implement this, here + * pargc is a pointer to the original argc, + * pargv is a pointer to the original argv, + * jrepath is an accessible path to the jre as determined by the call + * so_jrepath is the length of the buffer jrepath + * jvmpath is an accessible path to the jvm as determined by the call + * so_jvmpath is the length of the buffer jvmpath + */ +void CreateExecutionEnvironment(int *argc, char ***argv, + char *jrepath, jint so_jrepath, + char *jvmpath, jint so_jvmpath, + char *jvmcfg, jint so_jvmcfg); + +/* Reports an error message to stderr or a window as appropriate. */ +void JLI_ReportErrorMessage(const char * message, ...); + +/* Reports a system error message to stderr or a window */ +void JLI_ReportErrorMessageSys(const char * message, ...); + +/* Reports an error message only to stderr. */ +void JLI_ReportMessage(const char * message, ...); + +/* + * Reports an exception which terminates the vm to stderr or a window + * as appropriate. + */ +void JLI_ReportExceptionDescription(JNIEnv * env); +void PrintMachineDependentOptions(); + +const char *jlong_format_specifier(); + +/* + * Block current thread and continue execution in new thread + */ +int ContinueInNewThread0(int (JNICALL *continuation)(void *), + jlong stack_size, void * args); + +/* sun.java.launcher.* platform properties. */ +void SetJavaLauncherPlatformProps(void); +void SetJavaCommandLineProp(char* what, int argc, char** argv); +void SetJavaLauncherProp(void); + +/* + * Functions defined in java.c and used in java_md.c. + */ +jint ReadKnownVMs(const char *jvmcfg, jboolean speculative); +char *CheckJvmType(int *argc, char ***argv, jboolean speculative); +void AddOption(char *str, void *info); + +enum ergo_policy { + DEFAULT_POLICY = 0, + NEVER_SERVER_CLASS, + ALWAYS_SERVER_CLASS +}; + +const char* GetProgramName(); +const char* GetDotVersion(); +const char* GetFullVersion(); +jboolean IsJavaArgs(); +jboolean IsJavaw(); +jint GetErgoPolicy(); + +jboolean ServerClassMachine(); + +int ContinueInNewThread(InvocationFunctions* ifn, jlong threadStackSize, + int argc, char** argv, + int mode, char *what, int ret); + +int JVMInit(InvocationFunctions* ifn, jlong threadStackSize, + int argc, char** argv, + int mode, char *what, int ret); + +/* + * Initialize platform specific settings + */ +void InitLauncher(jboolean javaw); + +/* + * For MacOSX and Windows/Unix compatibility we require these + * entry points, some of them may be stubbed out on Windows/Unixes. + */ +void PostJVMInit(JNIEnv *env, jstring mainClass, JavaVM *vm); +void ShowSplashScreen(); +void RegisterThread(); +/* + * this method performs additional platform specific processing and + * should return JNI_TRUE to indicate the argument has been consumed, + * otherwise returns JNI_FALSE to allow the calling logic to further + * process the option. + */ +jboolean ProcessPlatformOption(const char *arg); + +/* + * This allows for finding classes from the VM's bootstrap class loader directly, + * FindClass uses the application class loader internally, this will cause + * unnecessary searching of the classpath for the required classes. + * + */ +typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env, + const char *name)); +jclass FindBootStrapClass(JNIEnv *env, const char *classname); + +jobjectArray CreateApplicationArgs(JNIEnv *env, char **strv, int argc); +jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc); +jclass GetLauncherHelperClass(JNIEnv *env); + +int JNICALL JavaMain(void * args); /* entry point */ + +enum LaunchMode { // cf. sun.launcher.LauncherHelper + LM_UNKNOWN = 0, + LM_CLASS, + LM_JAR +}; + +static const char *launchModeNames[] + = { "Unknown", "Main class", "JAR file" }; + +typedef struct { + int argc; + char **argv; + int mode; + char *what; + InvocationFunctions ifn; +} JavaMainArgs; + +#define NULL_CHECK_RETURN_VALUE(NCRV_check_pointer, NCRV_return_value) \ + do { \ + if ((NCRV_check_pointer) == NULL) { \ + JLI_ReportErrorMessage(JNI_ERROR); \ + return NCRV_return_value; \ + } \ + } while (JNI_FALSE) + +#define NULL_CHECK0(NC0_check_pointer) \ + NULL_CHECK_RETURN_VALUE(NC0_check_pointer, 0) + +#define NULL_CHECK(NC_check_pointer) \ + NULL_CHECK_RETURN_VALUE(NC_check_pointer, ) + +#define CHECK_EXCEPTION_RETURN() \ + do { \ + if ((*env)->ExceptionOccurred(env)) { \ + return; \ + } \ + } while (JNI_FALSE) + +/* + * For JNI calls : + * - check for thrown exceptions + * - check for null return + * + * JNI calls can return null and/or throw an exception. Check for these. + * + * : CHECK_JNI_RETURN_EXCEPTION() + * return the specified RETURNVALUE if exception was generated + * : CHECK_JNI_RETURN_0(JNISTATEMENT) : check if JNISTATEMENT was successful, return 0 if not + * : CHECK_JNI_RETURN_VOID(JNISTATEMENT) : check if JNISTATEMENT was successful, return void if not + * : CHECK_JNI_RETURN_VALUE(JNISTATEMENT,n) : check if JNISTATEMENT was successful, return n if not + * + * These macros need at least one parameter, the JNI statement [ JNISTATEMENT ]. + * + * E.G.: check the JNI statement, and specify a value to return if a failure was detected. + * + * CHECK_JNI_RETURN_VALUE(str = (*env)->CallStaticObjectMethod(env, cls, + * makePlatformStringMID, USE_STDERR, ary), -1); + */ + +#define RETURNVOID return +#define RETURN0 return 0 +#define RETURN(N) return (N) + +#define CHECK_JNI_RETURN_EXCEPTION(RETURNVALUE) \ + if ((((*env)->ExceptionOccurred(env))!=NULL)) { \ + RETURNVALUE; \ + } + +#define CHECK_JNI_RETURN_0(JNISTATEMENT) \ + CHECK_JNI_RETURN_EXCEPTION(RETURN0); \ + NULL_CHECK0(JNISTATEMENT); + +#define CHECK_JNI_RETURN_VOID(JNISTATEMENT) \ + CHECK_JNI_RETURN_EXCEPTION(RETURNVOID); \ + NULL_CHECK(JNISTATEMENT); + +#define CHECK_JNI_RETURN_VALUE(JNISTATEMENT, NCRV_return_value) \ + CHECK_JNI_RETURN_EXCEPTION(RETURN(NCRV_return_value)); \ + NULL_CHECK_RETURN_VALUE(JNISTATEMENT, NCRV_return_value); + + +#endif /* _JAVA_H_ */ diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java_md.c b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java_md.c new file mode 100644 index 0000000..2c8a4ac --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java_md.c @@ -0,0 +1,1521 @@ +/* + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "java.h" +#include "version_comp.h" + +#define JVM_DLL "jvm.dll" +#define JAVA_DLL "java.dll" + +/* + * Prototypes. + */ +static jboolean GetPublicJREHome(char *path, jint pathsize); +static jboolean GetJVMPath(const char *jrepath, const char *jvmtype, + char *jvmpath, jint jvmpathsize); +static jboolean GetJREPath(char *path, jint pathsize); + +/* We supports warmup for UI stack that is performed in parallel + * to VM initialization. + * This helps to improve startup of UI application as warmup phase + * might be long due to initialization of OS or hardware resources. + * It is not CPU bound and therefore it does not interfere with VM init. + * Obviously such warmup only has sense for UI apps and therefore it needs + * to be explicitly requested by passing -Dsun.awt.warmup=true property + * (this is always the case for plugin/javaws). + * + * Implementation launches new thread after VM starts and use it to perform + * warmup code (platform dependent). + * This thread is later reused as AWT toolkit thread as graphics toolkit + * often assume that they are used from the same thread they were launched on. + * + * At the moment we only support warmup for D3D. It only possible on windows + * and only if other flags do not prohibit this (e.g. OpenGL support requested). + */ +#undef ENABLE_AWT_PRELOAD +#ifndef JAVA_ARGS /* turn off AWT preloading for javac, jar, etc */ + /* CR6999872: fastdebug crashes if awt library is loaded before JVM is + * initialized*/ + #if !defined(DEBUG) + #define ENABLE_AWT_PRELOAD + #endif +#endif + +#ifdef ENABLE_AWT_PRELOAD +/* "AWT was preloaded" flag; + * turned on by AWTPreload(). + */ +int awtPreloaded = 0; + +/* Calls a function with the name specified + * the function must be int(*fn)(void). + */ +int AWTPreload(const char *funcName); +/* stops AWT preloading */ +void AWTPreloadStop(); + +/* D3D preloading */ +/* -1: not initialized; 0: OFF, 1: ON */ +int awtPreloadD3D = -1; +/* command line parameter to swith D3D preloading on */ +#define PARAM_PRELOAD_D3D "-Dsun.awt.warmup" +/* D3D/OpenGL management parameters */ +#define PARAM_NODDRAW "-Dsun.java2d.noddraw" +#define PARAM_D3D "-Dsun.java2d.d3d" +#define PARAM_OPENGL "-Dsun.java2d.opengl" +/* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */ +#define D3D_PRELOAD_FUNC "preloadD3D" + +/* Extracts value of a parameter with the specified name + * from command line argument (returns pointer in the argument). + * Returns NULL if the argument does not contains the parameter. + * e.g.: + * GetParamValue("theParam", "theParam=value") returns pointer to "value". + */ +const char * GetParamValue(const char *paramName, const char *arg) { + int nameLen = JLI_StrLen(paramName); + if (JLI_StrNCmp(paramName, arg, nameLen) == 0) { + /* arg[nameLen] is valid (may contain final NULL) */ + if (arg[nameLen] == '=') { + return arg + nameLen + 1; + } + } + return NULL; +} + +/* Checks if commandline argument contains property specified + * and analyze it as boolean property (true/false). + * Returns -1 if the argument does not contain the parameter; + * Returns 1 if the argument contains the parameter and its value is "true"; + * Returns 0 if the argument contains the parameter and its value is "false". + */ +int GetBoolParamValue(const char *paramName, const char *arg) { + const char * paramValue = GetParamValue(paramName, arg); + if (paramValue != NULL) { + if (JLI_StrCaseCmp(paramValue, "true") == 0) { + return 1; + } + if (JLI_StrCaseCmp(paramValue, "false") == 0) { + return 0; + } + } + return -1; +} +#endif /* ENABLE_AWT_PRELOAD */ + + +static jboolean _isjavaw = JNI_FALSE; + + +jboolean +IsJavaw() +{ + return _isjavaw; +} + +/* + * Returns the arch path, to get the current arch use the + * macro GetArch, nbits here is ignored for now. + */ +const char * +GetArchPath(int nbits) +{ +#ifdef _M_AMD64 + return "amd64"; +#elif defined(_M_IA64) + return "ia64"; +#else + return "i386"; +#endif +} + +/* + * + */ +void +CreateExecutionEnvironment(int *pargc, char ***pargv, + char *jrepath, jint so_jrepath, + char *jvmpath, jint so_jvmpath, + char *jvmcfg, jint so_jvmcfg) { + char * jvmtype; + int i = 0; + int running = CURRENT_DATA_MODEL; + + int wanted = running; + + char** argv = *pargv; + for (i = 1; i < *pargc ; i++) { + if (JLI_StrCmp(argv[i], "-J-d64") == 0 || JLI_StrCmp(argv[i], "-d64") == 0) { + wanted = 64; + continue; + } + if (JLI_StrCmp(argv[i], "-J-d32") == 0 || JLI_StrCmp(argv[i], "-d32") == 0) { + wanted = 32; + continue; + } + + if (IsJavaArgs() && argv[i][0] != '-') + continue; + if (argv[i][0] != '-') + break; + } + if (running != wanted) { + JLI_ReportErrorMessage(JRE_ERROR2, wanted); + exit(1); + } + + /* Find out where the JRE is that we will be using. */ + if (!GetJREPath(jrepath, so_jrepath)) { + JLI_ReportErrorMessage(JRE_ERROR1); + exit(2); + } + + JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg", + jrepath, FILESEP, FILESEP, (char*)GetArch(), FILESEP); + + /* Find the specified JVM type */ + if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) { + JLI_ReportErrorMessage(CFG_ERROR7); + exit(1); + } + + jvmtype = CheckJvmType(pargc, pargv, JNI_FALSE); + if (JLI_StrCmp(jvmtype, "ERROR") == 0) { + JLI_ReportErrorMessage(CFG_ERROR9); + exit(4); + } + + jvmpath[0] = '\0'; + if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath)) { + JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath); + exit(4); + } + /* If we got here, jvmpath has been correctly initialized. */ + + /* Check if we need preload AWT */ +#ifdef ENABLE_AWT_PRELOAD + argv = *pargv; + for (i = 0; i < *pargc ; i++) { + /* Tests the "turn on" parameter only if not set yet. */ + if (awtPreloadD3D < 0) { + if (GetBoolParamValue(PARAM_PRELOAD_D3D, argv[i]) == 1) { + awtPreloadD3D = 1; + } + } + /* Test parameters which can disable preloading if not already disabled. */ + if (awtPreloadD3D != 0) { + if (GetBoolParamValue(PARAM_NODDRAW, argv[i]) == 1 + || GetBoolParamValue(PARAM_D3D, argv[i]) == 0 + || GetBoolParamValue(PARAM_OPENGL, argv[i]) == 1) + { + awtPreloadD3D = 0; + /* no need to test the rest of the parameters */ + break; + } + } + } +#endif /* ENABLE_AWT_PRELOAD */ +} + + +static jboolean +LoadMSVCRT() +{ + // Only do this once + static int loaded = 0; + char crtpath[MAXPATHLEN]; + + if (!loaded) { + /* + * The Microsoft C Runtime Library needs to be loaded first. A copy is + * assumed to be present in the "JRE path" directory. If it is not found + * there (or "JRE path" fails to resolve), skip the explicit load and let + * nature take its course, which is likely to be a failure to execute. + * This is clearly completely specific to the exact compiler version + * which isn't very nice, but its hardly the only place. + * No attempt to look for compiler versions in between 2003 and 2010 + * as we aren't supporting building with those. + */ +#ifdef _MSC_VER +#if _MSC_VER < 1400 +#define CRT_DLL "msvcr71.dll" +#endif +#if _MSC_VER >= 1600 +#define CRT_DLL "msvcr100.dll" +#endif +#ifdef CRT_DLL + if (GetJREPath(crtpath, MAXPATHLEN)) { + if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") + + JLI_StrLen(CRT_DLL) >= MAXPATHLEN) { + JLI_ReportErrorMessage(JRE_ERROR11); + return JNI_FALSE; + } + (void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL); /* Add crt dll */ + JLI_TraceLauncher("CRT path is %s\n", crtpath); + if (_access(crtpath, 0) == 0) { + if (LoadLibrary(crtpath) == 0) { + JLI_ReportErrorMessage(DLL_ERROR4, crtpath); + return JNI_FALSE; + } + } + } +#endif /* CRT_DLL */ +#endif /* _MSC_VER */ + loaded = 1; + } + return JNI_TRUE; +} + + +/* + * Find path to JRE based on .exe's location or registry settings. + */ +jboolean +GetJREPath(char *path, jint pathsize) +{ + char javadll[MAXPATHLEN]; + struct stat s; + + if (GetApplicationHome(path, pathsize)) { + /* Is JRE co-located with the application? */ + JLI_Snprintf(javadll, sizeof(javadll), "%s\\bin\\" JAVA_DLL, path); + if (stat(javadll, &s) == 0) { + JLI_TraceLauncher("JRE path is %s\n", path); + return JNI_TRUE; + } + /* ensure storage for path + \jre + NULL */ + if ((JLI_StrLen(path) + 4 + 1) > pathsize) { + JLI_TraceLauncher("Insufficient space to store JRE path\n"); + return JNI_FALSE; + } + /* Does this app ship a private JRE in \jre directory? */ + JLI_Snprintf(javadll, sizeof (javadll), "%s\\jre\\bin\\" JAVA_DLL, path); + if (stat(javadll, &s) == 0) { + JLI_StrCat(path, "\\jre"); + JLI_TraceLauncher("JRE path is %s\n", path); + return JNI_TRUE; + } + } + + /* Look for a public JRE on this machine. */ + if (GetPublicJREHome(path, pathsize)) { + JLI_TraceLauncher("JRE path is %s\n", path); + return JNI_TRUE; + } + + JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL); + return JNI_FALSE; + +} + +/* + * Given a JRE location and a JVM type, construct what the name the + * JVM shared library will be. Return true, if such a library + * exists, false otherwise. + */ +static jboolean +GetJVMPath(const char *jrepath, const char *jvmtype, + char *jvmpath, jint jvmpathsize) +{ + struct stat s; + if (JLI_StrChr(jvmtype, '/') || JLI_StrChr(jvmtype, '\\')) { + JLI_Snprintf(jvmpath, jvmpathsize, "%s\\" JVM_DLL, jvmtype); + } else { + JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL, + jrepath, jvmtype); + } + if (stat(jvmpath, &s) == 0) { + return JNI_TRUE; + } else { + return JNI_FALSE; + } +} + +/* + * Load a jvm from "jvmpath" and initialize the invocation functions. + */ +jboolean +LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn) +{ + HINSTANCE handle; + + JLI_TraceLauncher("JVM path is %s\n", jvmpath); + + /* + * The Microsoft C Runtime Library needs to be loaded first. A copy is + * assumed to be present in the "JRE path" directory. If it is not found + * there (or "JRE path" fails to resolve), skip the explicit load and let + * nature take its course, which is likely to be a failure to execute. + * + */ + LoadMSVCRT(); + + /* Load the Java VM DLL */ + if ((handle = LoadLibrary(jvmpath)) == 0) { + JLI_ReportErrorMessage(DLL_ERROR4, (char *)jvmpath); + return JNI_FALSE; + } + + /* Now get the function addresses */ + ifn->CreateJavaVM = + (void *)GetProcAddress(handle, "JNI_CreateJavaVM"); + ifn->GetDefaultJavaVMInitArgs = + (void *)GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs"); + if (ifn->CreateJavaVM == 0 || ifn->GetDefaultJavaVMInitArgs == 0) { + JLI_ReportErrorMessage(JNI_ERROR1, (char *)jvmpath); + return JNI_FALSE; + } + + return JNI_TRUE; +} + +/* + * If app is "c:\foo\bin\javac", then put "c:\foo" into buf. + */ +jboolean +GetApplicationHome(char *buf, jint bufsize) +{ + char *cp; + GetModuleFileName(0, buf, bufsize); + *JLI_StrRChr(buf, '\\') = '\0'; /* remove .exe file name */ + if ((cp = JLI_StrRChr(buf, '\\')) == 0) { + /* This happens if the application is in a drive root, and + * there is no bin directory. */ + buf[0] = '\0'; + return JNI_FALSE; + } + *cp = '\0'; /* remove the bin\ part */ + return JNI_TRUE; +} + +/* + * Helpers to look in the registry for a public JRE. + */ + /* Same for 1.5.0, 1.5.1, 1.5.2 etc. */ +#define JRE_KEY "Software\\JavaSoft\\Java Runtime Environment" + +static jboolean +GetStringFromRegistry(HKEY key, const char *name, char *buf, jint bufsize) +{ + DWORD type, size; + + if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0 + && type == REG_SZ + && (size < (unsigned int)bufsize)) { + if (RegQueryValueEx(key, name, 0, 0, buf, &size) == 0) { + return JNI_TRUE; + } + } + return JNI_FALSE; +} + +static jboolean +GetPublicJREHome(char *buf, jint bufsize) +{ + HKEY key, subkey; + char version[MAXPATHLEN]; + + /* + * Note: There is a very similar implementation of the following + * registry reading code in the Windows java control panel (javacp.cpl). + * If there are bugs here, a similar bug probably exists there. Hence, + * changes here require inspection there. + */ + + /* Find the current version of the JRE */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_READ, &key) != 0) { + JLI_ReportErrorMessage(REG_ERROR1, JRE_KEY); + return JNI_FALSE; + } + + if (!GetStringFromRegistry(key, "CurrentVersion", + version, sizeof(version))) { + JLI_ReportErrorMessage(REG_ERROR2, JRE_KEY); + RegCloseKey(key); + return JNI_FALSE; + } + + if (JLI_StrCmp(version, GetDotVersion()) != 0) { + JLI_ReportErrorMessage(REG_ERROR3, JRE_KEY, version, GetDotVersion() + ); + RegCloseKey(key); + return JNI_FALSE; + } + + /* Find directory where the current version is installed. */ + if (RegOpenKeyEx(key, version, 0, KEY_READ, &subkey) != 0) { + JLI_ReportErrorMessage(REG_ERROR1, JRE_KEY, version); + RegCloseKey(key); + return JNI_FALSE; + } + + if (!GetStringFromRegistry(subkey, "JavaHome", buf, bufsize)) { + JLI_ReportErrorMessage(REG_ERROR4, JRE_KEY, version); + RegCloseKey(key); + RegCloseKey(subkey); + return JNI_FALSE; + } + + if (JLI_IsTraceLauncher()) { + char micro[MAXPATHLEN]; + if (!GetStringFromRegistry(subkey, "MicroVersion", micro, + sizeof(micro))) { + printf("Warning: Can't read MicroVersion\n"); + micro[0] = '\0'; + } + printf("Version major.minor.micro = %s.%s\n", version, micro); + } + + RegCloseKey(key); + RegCloseKey(subkey); + return JNI_TRUE; +} + +/* + * Support for doing cheap, accurate interval timing. + */ +static jboolean counterAvailable = JNI_FALSE; +static jboolean counterInitialized = JNI_FALSE; +static LARGE_INTEGER counterFrequency; + +jlong CounterGet() +{ + LARGE_INTEGER count; + + if (!counterInitialized) { + counterAvailable = QueryPerformanceFrequency(&counterFrequency); + counterInitialized = JNI_TRUE; + } + if (!counterAvailable) { + return 0; + } + QueryPerformanceCounter(&count); + return (jlong)(count.QuadPart); +} + +jlong Counter2Micros(jlong counts) +{ + if (!counterAvailable || !counterInitialized) { + return 0; + } + return (counts * 1000 * 1000)/counterFrequency.QuadPart; +} +/* + * windows snprintf does not guarantee a null terminator in the buffer, + * if the computed size is equal to or greater than the buffer size, + * as well as error conditions. This function guarantees a null terminator + * under all these conditions. An unreasonable buffer or size will return + * an error value. Under all other conditions this function will return the + * size of the bytes actually written minus the null terminator, similar + * to ansi snprintf api. Thus when calling this function the caller must + * ensure storage for the null terminator. + */ +int +JLI_Snprintf(char* buffer, size_t size, const char* format, ...) { + int rc; + va_list vl; + if (size == 0 || buffer == NULL) + return -1; + buffer[0] = '\0'; + va_start(vl, format); + rc = vsnprintf(buffer, size, format, vl); + va_end(vl); + /* force a null terminator, if something is amiss */ + if (rc < 0) { + /* apply ansi semantics */ + buffer[size - 1] = '\0'; + return size; + } else if (rc == size) { + /* force a null terminator */ + buffer[size - 1] = '\0'; + } + return rc; +} + +void +JLI_ReportErrorMessage(const char* fmt, ...) { + va_list vl; + va_start(vl,fmt); + + if (IsJavaw()) { + char *message; + + /* get the length of the string we need */ + int n = _vscprintf(fmt, vl); + + message = (char *)JLI_MemAlloc(n + 1); + _vsnprintf(message, n, fmt, vl); + message[n]='\0'; + MessageBox(NULL, message, "Java Virtual Machine Launcher", + (MB_OK|MB_ICONSTOP|MB_APPLMODAL)); + JLI_MemFree(message); + } else { + vfprintf(stderr, fmt, vl); + fprintf(stderr, "\n"); + } + va_end(vl); +} + +/* + * Just like JLI_ReportErrorMessage, except that it concatenates the system + * error message if any, its upto the calling routine to correctly + * format the separation of the messages. + */ +void +JLI_ReportErrorMessageSys(const char *fmt, ...) +{ + va_list vl; + + int save_errno = errno; + DWORD errval; + jboolean freeit = JNI_FALSE; + char *errtext = NULL; + + va_start(vl, fmt); + + if ((errval = GetLastError()) != 0) { /* Platform SDK / DOS Error */ + int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM| + FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, errval, 0, (LPTSTR)&errtext, 0, NULL); + if (errtext == NULL || n == 0) { /* Paranoia check */ + errtext = ""; + n = 0; + } else { + freeit = JNI_TRUE; + if (n > 2) { /* Drop final CR, LF */ + if (errtext[n - 1] == '\n') n--; + if (errtext[n - 1] == '\r') n--; + errtext[n] = '\0'; + } + } + } else { /* C runtime error that has no corresponding DOS error code */ + errtext = strerror(save_errno); + } + + if (IsJavaw()) { + char *message; + int mlen; + /* get the length of the string we need */ + int len = mlen = _vscprintf(fmt, vl) + 1; + if (freeit) { + mlen += (int)JLI_StrLen(errtext); + } + + message = (char *)JLI_MemAlloc(mlen); + _vsnprintf(message, len, fmt, vl); + message[len]='\0'; + + if (freeit) { + JLI_StrCat(message, errtext); + } + + MessageBox(NULL, message, "Java Virtual Machine Launcher", + (MB_OK|MB_ICONSTOP|MB_APPLMODAL)); + + JLI_MemFree(message); + } else { + vfprintf(stderr, fmt, vl); + if (freeit) { + fprintf(stderr, "%s", errtext); + } + } + if (freeit) { + (void)LocalFree((HLOCAL)errtext); + } + va_end(vl); +} + +void JLI_ReportExceptionDescription(JNIEnv * env) { + if (IsJavaw()) { + /* + * This code should be replaced by code which opens a window with + * the exception detail message, for now atleast put a dialog up. + */ + MessageBox(NULL, "A Java Exception has occurred.", "Java Virtual Machine Launcher", + (MB_OK|MB_ICONSTOP|MB_APPLMODAL)); + } else { + (*env)->ExceptionDescribe(env); + } +} + +jboolean +ServerClassMachine() { + return (GetErgoPolicy() == ALWAYS_SERVER_CLASS) ? JNI_TRUE : JNI_FALSE; +} + +/* + * Determine if there is an acceptable JRE in the registry directory top_key. + * Upon locating the "best" one, return a fully qualified path to it. + * "Best" is defined as the most advanced JRE meeting the constraints + * contained in the manifest_info. If no JRE in this directory meets the + * constraints, return NULL. + * + * It doesn't matter if we get an error reading the registry, or we just + * don't find anything interesting in the directory. We just return NULL + * in either case. + */ +static char * +ProcessDir(manifest_info* info, HKEY top_key) { + DWORD index = 0; + HKEY ver_key; + char name[MAXNAMELEN]; + int len; + char *best = NULL; + + /* + * Enumerate "/SOFTWARE/JavaSoft/Java Runtime Environment" + * searching for the best available version. + */ + while (RegEnumKey(top_key, index, name, MAXNAMELEN) == ERROR_SUCCESS) { + index++; + if (JLI_AcceptableRelease(name, info->jre_version)) + if ((best == NULL) || (JLI_ExactVersionId(name, best) > 0)) { + if (best != NULL) + JLI_MemFree(best); + best = JLI_StringDup(name); + } + } + + /* + * Extract "JavaHome" from the "best" registry directory and return + * that path. If no appropriate version was located, or there is an + * error in extracting the "JavaHome" string, return null. + */ + if (best == NULL) + return (NULL); + else { + if (RegOpenKeyEx(top_key, best, 0, KEY_READ, &ver_key) + != ERROR_SUCCESS) { + JLI_MemFree(best); + if (ver_key != NULL) + RegCloseKey(ver_key); + return (NULL); + } + JLI_MemFree(best); + len = MAXNAMELEN; + if (RegQueryValueEx(ver_key, "JavaHome", NULL, NULL, (LPBYTE)name, &len) + != ERROR_SUCCESS) { + if (ver_key != NULL) + RegCloseKey(ver_key); + return (NULL); + } + if (ver_key != NULL) + RegCloseKey(ver_key); + return (JLI_StringDup(name)); + } +} + +/* + * This is the global entry point. It examines the host for the optimal + * JRE to be used by scanning a set of registry entries. This set of entries + * is hardwired on Windows as "Software\JavaSoft\Java Runtime Environment" + * under the set of roots "{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }". + * + * This routine simply opens each of these registry directories before passing + * control onto ProcessDir(). + */ +char * +LocateJRE(manifest_info* info) { + HKEY key = NULL; + char *path; + int key_index; + HKEY root_keys[2] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }; + + for (key_index = 0; key_index <= 1; key_index++) { + if (RegOpenKeyEx(root_keys[key_index], JRE_KEY, 0, KEY_READ, &key) + == ERROR_SUCCESS) + if ((path = ProcessDir(info, key)) != NULL) { + if (key != NULL) + RegCloseKey(key); + return (path); + } + if (key != NULL) + RegCloseKey(key); + } + return NULL; +} + +/* + * Local helper routine to isolate a single token (option or argument) + * from the command line. + * + * This routine accepts a pointer to a character pointer. The first + * token (as defined by MSDN command-line argument syntax) is isolated + * from that string. + * + * Upon return, the input character pointer pointed to by the parameter s + * is updated to point to the remainding, unscanned, portion of the string, + * or to a null character if the entire string has been consummed. + * + * This function returns a pointer to a null-terminated string which + * contains the isolated first token, or to the null character if no + * token could be isolated. + * + * Note the side effect of modifying the input string s by the insertion + * of a null character, making it two strings. + * + * See "Parsing C Command-Line Arguments" in the MSDN Library for the + * parsing rule details. The rule summary from that specification is: + * + * * Arguments are delimited by white space, which is either a space or a tab. + * + * * A string surrounded by double quotation marks is interpreted as a single + * argument, regardless of white space contained within. A quoted string can + * be embedded in an argument. Note that the caret (^) is not recognized as + * an escape character or delimiter. + * + * * A double quotation mark preceded by a backslash, \", is interpreted as a + * literal double quotation mark ("). + * + * * Backslashes are interpreted literally, unless they immediately precede a + * double quotation mark. + * + * * If an even number of backslashes is followed by a double quotation mark, + * then one backslash (\) is placed in the argv array for every pair of + * backslashes (\\), and the double quotation mark (") is interpreted as a + * string delimiter. + * + * * If an odd number of backslashes is followed by a double quotation mark, + * then one backslash (\) is placed in the argv array for every pair of + * backslashes (\\) and the double quotation mark is interpreted as an + * escape sequence by the remaining backslash, causing a literal double + * quotation mark (") to be placed in argv. + */ +static char* +nextarg(char** s) { + char *p = *s; + char *head; + int slashes = 0; + int inquote = 0; + + /* + * Strip leading whitespace, which MSDN defines as only space or tab. + * (Hence, no locale specific "isspace" here.) + */ + while (*p != (char)0 && (*p == ' ' || *p == '\t')) + p++; + head = p; /* Save the start of the token to return */ + + /* + * Isolate a token from the command line. + */ + while (*p != (char)0 && (inquote || !(*p == ' ' || *p == '\t'))) { + if (*p == '\\' && *(p+1) == '"' && slashes % 2 == 0) + p++; + else if (*p == '"') + inquote = !inquote; + slashes = (*p++ == '\\') ? slashes + 1 : 0; + } + + /* + * If the token isolated isn't already terminated in a "char zero", + * then replace the whitespace character with one and move to the + * next character. + */ + if (*p != (char)0) + *p++ = (char)0; + + /* + * Update the parameter to point to the head of the remaining string + * reflecting the command line and return a pointer to the leading + * token which was isolated from the command line. + */ + *s = p; + return (head); +} + +/* + * Local helper routine to return a string equivalent to the input string + * s, but with quotes removed so the result is a string as would be found + * in argv[]. The returned string should be freed by a call to JLI_MemFree(). + * + * The rules for quoting (and escaped quotes) are: + * + * 1 A double quotation mark preceded by a backslash, \", is interpreted as a + * literal double quotation mark ("). + * + * 2 Backslashes are interpreted literally, unless they immediately precede a + * double quotation mark. + * + * 3 If an even number of backslashes is followed by a double quotation mark, + * then one backslash (\) is placed in the argv array for every pair of + * backslashes (\\), and the double quotation mark (") is interpreted as a + * string delimiter. + * + * 4 If an odd number of backslashes is followed by a double quotation mark, + * then one backslash (\) is placed in the argv array for every pair of + * backslashes (\\) and the double quotation mark is interpreted as an + * escape sequence by the remaining backslash, causing a literal double + * quotation mark (") to be placed in argv. + */ +static char* +unquote(const char *s) { + const char *p = s; /* Pointer to the tail of the original string */ + char *un = (char*)JLI_MemAlloc(JLI_StrLen(s) + 1); /* Ptr to unquoted string */ + char *pun = un; /* Pointer to the tail of the unquoted string */ + + while (*p != '\0') { + if (*p == '"') { + p++; + } else if (*p == '\\') { + const char *q = p + JLI_StrSpn(p,"\\"); + if (*q == '"') + do { + *pun++ = '\\'; + p += 2; + } while (*p == '\\' && p < q); + else + while (p < q) + *pun++ = *p++; + } else { + *pun++ = *p++; + } + } + *pun = '\0'; + return un; +} + +/* + * Given a path to a jre to execute, this routine checks if this process + * is indeed that jre. If not, it exec's that jre. + * + * We want to actually check the paths rather than just the version string + * built into the executable, so that given version specification will yield + * the exact same Java environment, regardless of the version of the arbitrary + * launcher we start with. + */ +void +ExecJRE(char *jre, char **argv) { + jint len; + char path[MAXPATHLEN + 1]; + + const char *progname = GetProgramName(); + + /* + * Resolve the real path to the currently running launcher. + */ + len = GetModuleFileName(NULL, path, MAXPATHLEN + 1); + if (len == 0 || len > MAXPATHLEN) { + JLI_ReportErrorMessageSys(JRE_ERROR9, progname); + exit(1); + } + + JLI_TraceLauncher("ExecJRE: old: %s\n", path); + JLI_TraceLauncher("ExecJRE: new: %s\n", jre); + + /* + * If the path to the selected JRE directory is a match to the initial + * portion of the path to the currently executing JRE, we have a winner! + * If so, just return. + */ + if (JLI_StrNCaseCmp(jre, path, JLI_StrLen(jre)) == 0) + return; /* I am the droid you were looking for */ + + /* + * If this isn't the selected version, exec the selected version. + */ + JLI_Snprintf(path, sizeof(path), "%s\\bin\\%s.exe", jre, progname); + + /* + * Although Windows has an execv() entrypoint, it doesn't actually + * overlay a process: it can only create a new process and terminate + * the old process. Therefore, any processes waiting on the initial + * process wake up and they shouldn't. Hence, a chain of pseudo-zombie + * processes must be retained to maintain the proper wait semantics. + * Fortunately the image size of the launcher isn't too large at this + * time. + * + * If it weren't for this semantic flaw, the code below would be ... + * + * execv(path, argv); + * JLI_ReportErrorMessage("Error: Exec of %s failed\n", path); + * exit(1); + * + * The incorrect exec semantics could be addressed by: + * + * exit((int)spawnv(_P_WAIT, path, argv)); + * + * Unfortunately, a bug in Windows spawn/exec impementation prevents + * this from completely working. All the Windows POSIX process creation + * interfaces are implemented as wrappers around the native Windows + * function CreateProcess(). CreateProcess() takes a single string + * to specify command line options and arguments, so the POSIX routine + * wrappers build a single string from the argv[] array and in the + * process, any quoting information is lost. + * + * The solution to this to get the original command line, to process it + * to remove the new multiple JRE options (if any) as was done for argv + * in the common SelectVersion() routine and finally to pass it directly + * to the native CreateProcess() Windows process control interface. + */ + { + char *cmdline; + char *p; + char *np; + char *ocl; + char *ccl; + char *unquoted; + DWORD exitCode; + STARTUPINFO si; + PROCESS_INFORMATION pi; + + /* + * The following code block gets and processes the original command + * line, replacing the argv[0] equivalent in the command line with + * the path to the new executable and removing the appropriate + * Multiple JRE support options. Note that similar logic exists + * in the platform independent SelectVersion routine, but is + * replicated here due to the syntax of CreateProcess(). + * + * The magic "+ 4" characters added to the command line length are + * 2 possible quotes around the path (argv[0]), a space after the + * path and a terminating null character. + */ + ocl = GetCommandLine(); + np = ccl = JLI_StringDup(ocl); + p = nextarg(&np); /* Discard argv[0] */ + cmdline = (char *)JLI_MemAlloc(JLI_StrLen(path) + JLI_StrLen(np) + 4); + if (JLI_StrChr(path, (int)' ') == NULL && JLI_StrChr(path, (int)'\t') == NULL) + cmdline = JLI_StrCpy(cmdline, path); + else + cmdline = JLI_StrCat(JLI_StrCat(JLI_StrCpy(cmdline, "\""), path), "\""); + + while (*np != (char)0) { /* While more command-line */ + p = nextarg(&np); + if (*p != (char)0) { /* If a token was isolated */ + unquoted = unquote(p); + if (*unquoted == '-') { /* Looks like an option */ + if (JLI_StrCmp(unquoted, "-classpath") == 0 || + JLI_StrCmp(unquoted, "-cp") == 0) { /* Unique cp syntax */ + cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), p); + p = nextarg(&np); + if (*p != (char)0) /* If a token was isolated */ + cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), p); + } else if (JLI_StrNCmp(unquoted, "-version:", 9) != 0 && + JLI_StrCmp(unquoted, "-jre-restrict-search") != 0 && + JLI_StrCmp(unquoted, "-no-jre-restrict-search") != 0) { + cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), p); + } + } else { /* End of options */ + cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), p); + cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), np); + JLI_MemFree((void *)unquoted); + break; + } + JLI_MemFree((void *)unquoted); + } + } + JLI_MemFree((void *)ccl); + + if (JLI_IsTraceLauncher()) { + np = ccl = JLI_StringDup(cmdline); + p = nextarg(&np); + printf("ReExec Command: %s (%s)\n", path, p); + printf("ReExec Args: %s\n", np); + JLI_MemFree((void *)ccl); + } + (void)fflush(stdout); + (void)fflush(stderr); + + /* + * The following code is modeled after a model presented in the + * Microsoft Technical Article "Moving Unix Applications to + * Windows NT" (March 6, 1994) and "Creating Processes" on MSDN + * (Februrary 2005). It approximates UNIX spawn semantics with + * the parent waiting for termination of the child. + */ + memset(&si, 0, sizeof(si)); + si.cb =sizeof(STARTUPINFO); + memset(&pi, 0, sizeof(pi)); + + if (!CreateProcess((LPCTSTR)path, /* executable name */ + (LPTSTR)cmdline, /* command line */ + (LPSECURITY_ATTRIBUTES)NULL, /* process security attr. */ + (LPSECURITY_ATTRIBUTES)NULL, /* thread security attr. */ + (BOOL)TRUE, /* inherits system handles */ + (DWORD)0, /* creation flags */ + (LPVOID)NULL, /* environment block */ + (LPCTSTR)NULL, /* current directory */ + (LPSTARTUPINFO)&si, /* (in) startup information */ + (LPPROCESS_INFORMATION)&pi)) { /* (out) process information */ + JLI_ReportErrorMessageSys(SYS_ERROR1, path); + exit(1); + } + + if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) { + if (GetExitCodeProcess(pi.hProcess, &exitCode) == FALSE) + exitCode = 1; + } else { + JLI_ReportErrorMessage(SYS_ERROR2); + exitCode = 1; + } + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + exit(exitCode); + } +} + +/* + * Wrapper for platform dependent unsetenv function. + */ +int +UnsetEnv(char *name) +{ + int ret; + char *buf = JLI_MemAlloc(JLI_StrLen(name) + 2); + buf = JLI_StrCat(JLI_StrCpy(buf, name), "="); + ret = _putenv(buf); + JLI_MemFree(buf); + return (ret); +} + +/* --- Splash Screen shared library support --- */ + +static const char* SPLASHSCREEN_SO = "\\bin\\splashscreen.dll"; + +static HMODULE hSplashLib = NULL; + +void* SplashProcAddress(const char* name) { + char libraryPath[MAXPATHLEN]; /* some extra space for JLI_StrCat'ing SPLASHSCREEN_SO */ + + if (!GetJREPath(libraryPath, MAXPATHLEN)) { + return NULL; + } + if (JLI_StrLen(libraryPath)+JLI_StrLen(SPLASHSCREEN_SO) >= MAXPATHLEN) { + return NULL; + } + JLI_StrCat(libraryPath, SPLASHSCREEN_SO); + + if (!hSplashLib) { + hSplashLib = LoadLibrary(libraryPath); + } + if (hSplashLib) { + return GetProcAddress(hSplashLib, name); + } else { + return NULL; + } +} + +void SplashFreeLibrary() { + if (hSplashLib) { + FreeLibrary(hSplashLib); + hSplashLib = NULL; + } +} + +const char * +jlong_format_specifier() { + return "%I64d"; +} + +/* + * Block current thread and continue execution in a new thread + */ +int +ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) { + int rslt = 0; + unsigned thread_id; + +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION +#define STACK_SIZE_PARAM_IS_A_RESERVATION (0x10000) +#endif + + /* + * STACK_SIZE_PARAM_IS_A_RESERVATION is what we want, but it's not + * supported on older version of Windows. Try first with the flag; and + * if that fails try again without the flag. See MSDN document or HotSpot + * source (os_win32.cpp) for details. + */ + HANDLE thread_handle = + (HANDLE)_beginthreadex(NULL, + (unsigned)stack_size, + continuation, + args, + STACK_SIZE_PARAM_IS_A_RESERVATION, + &thread_id); + if (thread_handle == NULL) { + thread_handle = + (HANDLE)_beginthreadex(NULL, + (unsigned)stack_size, + continuation, + args, + 0, + &thread_id); + } + + /* AWT preloading (AFTER main thread start) */ +#ifdef ENABLE_AWT_PRELOAD + /* D3D preloading */ + if (awtPreloadD3D != 0) { + char *envValue; + /* D3D routines checks env.var J2D_D3D if no appropriate + * command line params was specified + */ + envValue = getenv("J2D_D3D"); + if (envValue != NULL && JLI_StrCaseCmp(envValue, "false") == 0) { + awtPreloadD3D = 0; + } + /* Test that AWT preloading isn't disabled by J2D_D3D_PRELOAD env.var */ + envValue = getenv("J2D_D3D_PRELOAD"); + if (envValue != NULL && JLI_StrCaseCmp(envValue, "false") == 0) { + awtPreloadD3D = 0; + } + if (awtPreloadD3D < 0) { + /* If awtPreloadD3D is still undefined (-1), test + * if it is turned on by J2D_D3D_PRELOAD env.var. + * By default it's turned OFF. + */ + awtPreloadD3D = 0; + if (envValue != NULL && JLI_StrCaseCmp(envValue, "true") == 0) { + awtPreloadD3D = 1; + } + } + } + if (awtPreloadD3D) { + AWTPreload(D3D_PRELOAD_FUNC); + } +#endif /* ENABLE_AWT_PRELOAD */ + + if (thread_handle) { + WaitForSingleObject(thread_handle, INFINITE); + GetExitCodeThread(thread_handle, &rslt); + CloseHandle(thread_handle); + } else { + rslt = continuation(args); + } + +#ifdef ENABLE_AWT_PRELOAD + if (awtPreloaded) { + AWTPreloadStop(); + } +#endif /* ENABLE_AWT_PRELOAD */ + + return rslt; +} + +/* Unix only, empty on windows. */ +void SetJavaLauncherPlatformProps() {} + +/* + * The implementation for finding classes from the bootstrap + * class loader, refer to java.h + */ +static FindClassFromBootLoader_t *findBootClass = NULL; + +jclass FindBootStrapClass(JNIEnv *env, const char *classname) +{ + HMODULE hJvm; + + if (findBootClass == NULL) { + hJvm = GetModuleHandle(JVM_DLL); + if (hJvm == NULL) return NULL; + /* need to use the demangled entry point */ + findBootClass = (FindClassFromBootLoader_t *)GetProcAddress(hJvm, + "JVM_FindClassFromBootLoader"); + if (findBootClass == NULL) { + JLI_ReportErrorMessage(DLL_ERROR4, "JVM_FindClassFromBootLoader"); + return NULL; + } + } + return findBootClass(env, classname); +} + +void +InitLauncher(boolean javaw) +{ + INITCOMMONCONTROLSEX icx; + + /* + * Required for javaw mode MessageBox output as well as for + * HotSpot -XX:+ShowMessageBoxOnError in java mode, an empty + * flag field is sufficient to perform the basic UI initialization. + */ + memset(&icx, 0, sizeof(INITCOMMONCONTROLSEX)); + icx.dwSize = sizeof(INITCOMMONCONTROLSEX); + InitCommonControlsEx(&icx); + _isjavaw = javaw; + JLI_SetTraceLauncher(); +} + + +/* ============================== */ +/* AWT preloading */ +#ifdef ENABLE_AWT_PRELOAD + +typedef int FnPreloadStart(void); +typedef void FnPreloadStop(void); +static FnPreloadStop *fnPreloadStop = NULL; +static HMODULE hPreloadAwt = NULL; + +/* + * Starts AWT preloading + */ +int AWTPreload(const char *funcName) +{ + int result = -1; + /* load AWT library once (if several preload function should be called) */ + if (hPreloadAwt == NULL) { + /* awt.dll is not loaded yet */ + char libraryPath[MAXPATHLEN]; + int jrePathLen = 0; + HMODULE hJava = NULL; + HMODULE hVerify = NULL; + + while (1) { + /* awt.dll depends on jvm.dll & java.dll; + * jvm.dll is already loaded, so we need only java.dll; + * java.dll depends on MSVCRT lib & verify.dll. + */ + if (!GetJREPath(libraryPath, MAXPATHLEN)) { + break; + } + + /* save path length */ + jrePathLen = JLI_StrLen(libraryPath); + + if (jrePathLen + JLI_StrLen("\\bin\\verify.dll") >= MAXPATHLEN) { + /* jre path is too long, the library path will not fit there; + * report and abort preloading + */ + JLI_ReportErrorMessage(JRE_ERROR11); + break; + } + + /* load msvcrt 1st */ + LoadMSVCRT(); + + /* load verify.dll */ + JLI_StrCat(libraryPath, "\\bin\\verify.dll"); + hVerify = LoadLibrary(libraryPath); + if (hVerify == NULL) { + break; + } + + /* restore jrePath */ + libraryPath[jrePathLen] = 0; + /* load java.dll */ + JLI_StrCat(libraryPath, "\\bin\\" JAVA_DLL); + hJava = LoadLibrary(libraryPath); + if (hJava == NULL) { + break; + } + + /* restore jrePath */ + libraryPath[jrePathLen] = 0; + /* load awt.dll */ + JLI_StrCat(libraryPath, "\\bin\\awt.dll"); + hPreloadAwt = LoadLibrary(libraryPath); + if (hPreloadAwt == NULL) { + break; + } + + /* get "preloadStop" func ptr */ + fnPreloadStop = (FnPreloadStop *)GetProcAddress(hPreloadAwt, "preloadStop"); + + break; + } + } + + if (hPreloadAwt != NULL) { + FnPreloadStart *fnInit = (FnPreloadStart *)GetProcAddress(hPreloadAwt, funcName); + if (fnInit != NULL) { + /* don't forget to stop preloading */ + awtPreloaded = 1; + + result = fnInit(); + } + } + + return result; +} + +/* + * Terminates AWT preloading + */ +void AWTPreloadStop() { + if (fnPreloadStop != NULL) { + fnPreloadStop(); + } +} + +#endif /* ENABLE_AWT_PRELOAD */ + +int +JVMInit(InvocationFunctions* ifn, jlong threadStackSize, + int argc, char **argv, + int mode, char *what, int ret) +{ + ShowSplashScreen(); + return ContinueInNewThread(ifn, threadStackSize, argc, argv, mode, what, ret); +} + +void +PostJVMInit(JNIEnv *env, jstring mainClass, JavaVM *vm) +{ + // stubbed out for windows and *nixes. +} + +void +RegisterThread() +{ + // stubbed out for windows and *nixes. +} + +/* + * on windows, we return a false to indicate this option is not applicable + */ +jboolean +ProcessPlatformOption(const char *arg) +{ + return JNI_FALSE; +} + +int +filterArgs(StdArg *stdargs, const int nargc, StdArg **pargv) { + StdArg* argv = NULL; + int nargs = 0; + int i; + + /* Copy the non-vm args */ + for (i = 0; i < nargc ; i++) { + const char *arg = stdargs[i].arg; + if (arg[0] == '-' && arg[1] == 'J') + continue; + argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg)); + argv[nargs].arg = JLI_StringDup(arg); + argv[nargs].has_wildcard = stdargs[i].has_wildcard; + nargs++; + } + *pargv = argv; + return nargs; +} + +/* + * At this point we have the arguments to the application, and we need to + * check with original stdargs in order to compare which of these truly + * needs expansion. cmdtoargs will specify this if it finds a bare + * (unquoted) argument containing a glob character(s) ie. * or ? + */ +jobjectArray +CreateApplicationArgs(JNIEnv *env, char **strv, int argc) +{ + int i, j, idx, tlen; + jobjectArray outArray, inArray; + char *ostart, *astart, **nargv; + jboolean needs_expansion = JNI_FALSE; + jmethodID mid; + int filteredargc, stdargc; + StdArg *stdargs; + StdArg *filteredargs; + jclass cls = GetLauncherHelperClass(env); + NULL_CHECK0(cls); + + if (argc == 0) { + return NewPlatformStringArray(env, strv, argc); + } + // the holy grail we need to compare with. + stdargs = JLI_GetStdArgs(); + stdargc = JLI_GetStdArgc(); + + filteredargc = filterArgs(stdargs, stdargc, &filteredargs); + + // sanity check, this should never happen + if (argc > stdargc) { + JLI_TraceLauncher("Warning: app args is larger than the original, %d %d\n", argc, stdargc); + JLI_TraceLauncher("passing arguments as-is.\n"); + return NewPlatformStringArray(env, strv, argc); + } + + // sanity check, match the args we have, to the holy grail + idx = filteredargc - argc; + ostart = filteredargs[idx].arg; + astart = strv[0]; + // sanity check, ensure that the first argument of the arrays are the same + if (JLI_StrCmp(ostart, astart) != 0) { + // some thing is amiss the args don't match + JLI_TraceLauncher("Warning: app args parsing error\n"); + JLI_TraceLauncher("passing arguments as-is\n"); + return NewPlatformStringArray(env, strv, argc); + } + + // make a copy of the args which will be expanded in java if required. + nargv = (char **)JLI_MemAlloc(argc * sizeof(char*)); + for (i = 0, j = idx; i < argc; i++, j++) { + jboolean arg_expand = (JLI_StrCmp(filteredargs[j].arg, strv[i]) == 0) + ? filteredargs[j].has_wildcard + : JNI_FALSE; + if (needs_expansion == JNI_FALSE) + needs_expansion = arg_expand; + + // indicator char + String + NULL terminator, the java method will strip + // out the first character, the indicator character, so no matter what + // we add the indicator + tlen = 1 + JLI_StrLen(strv[i]) + 1; + nargv[i] = (char *) JLI_MemAlloc(tlen); + if (JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F', + strv[i]) < 0) { + return NULL; + } + JLI_TraceLauncher("%s\n", nargv[i]); + } + + if (!needs_expansion) { + // clean up any allocated memory and return back the old arguments + for (i = 0 ; i < argc ; i++) { + JLI_MemFree(nargv[i]); + } + JLI_MemFree(nargv); + return NewPlatformStringArray(env, strv, argc); + } + NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, + "expandArgs", + "([Ljava/lang/String;)[Ljava/lang/String;")); + + // expand the arguments that require expansion, the java method will strip + // out the indicator character. + inArray = NewPlatformStringArray(env, nargv, argc); + outArray = (*env)->CallStaticObjectMethod(env, cls, mid, inArray); + for (i = 0; i < argc; i++) { + JLI_MemFree(nargv[i]); + } + JLI_MemFree(nargv); + JLI_MemFree(filteredargs); + return outArray; +} diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java_md.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java_md.h new file mode 100644 index 0000000..bd3e9b9 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/java_md.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef JAVA_MD_H +#define JAVA_MD_H + +#include +#include +#include +#include "manifest_info.h" +#include "jli_util.h" + +#define PATH_SEPARATOR ';' +#define FILESEP "\\" +#define FILE_SEPARATOR '\\' +#define IS_FILE_SEPARATOR(c) ((c) == '\\' || (c) == '/') +#define MAXPATHLEN MAX_PATH +#define MAXNAMELEN MAX_PATH + + +/* + * Support for doing cheap, accurate interval timing. + */ +extern jlong CounterGet(void); +extern jlong Counter2Micros(jlong counts); + + +/* + * Function prototypes. + */ +char *LocateJRE(manifest_info *info); +void ExecJRE(char *jre, char **argv); +int UnsetEnv(char *name); + +#endif /* JAVA_MD_H */ diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/jli_util.c b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/jli_util.c new file mode 100644 index 0000000..4f2bed8 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/jli_util.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#include +#include +#include + +#include "jli_util.h" + +/* + * Returns a pointer to a block of at least 'size' bytes of memory. + * Prints error message and exits if the memory could not be allocated. + */ +void * +JLI_MemAlloc(size_t size) +{ + void *p = malloc(size); + if (p == 0) { + perror("malloc"); + exit(1); + } + return p; +} + +/* + * Equivalent to realloc(size). + * Prints error message and exits if the memory could not be reallocated. + */ +void * +JLI_MemRealloc(void *ptr, size_t size) +{ + void *p = realloc(ptr, size); + if (p == 0) { + perror("realloc"); + exit(1); + } + return p; +} + +/* + * Wrapper over strdup(3C) which prints an error message and exits if memory + * could not be allocated. + */ +char * +JLI_StringDup(const char *s1) +{ + char *s = strdup(s1); + if (s == NULL) { + perror("strdup"); + exit(1); + } + return s; +} + +/* + * Very equivalent to free(ptr). + * Here to maintain pairing with the above routines. + */ +void +JLI_MemFree(void *ptr) +{ + free(ptr); +} + +/* + * debug helpers we use + */ +static jboolean _launcher_debug = JNI_FALSE; + +void +JLI_TraceLauncher(const char* fmt, ...) +{ + va_list vl; + if (_launcher_debug != JNI_TRUE) return; + va_start(vl, fmt); + vprintf(fmt,vl); + va_end(vl); +} + +void +JLI_SetTraceLauncher() +{ + if (getenv(JLDEBUG_ENV_ENTRY) != 0) { + _launcher_debug = JNI_TRUE; + JLI_TraceLauncher("----%s----\n", JLDEBUG_ENV_ENTRY); + } +} + +jboolean +JLI_IsTraceLauncher() +{ + return _launcher_debug; +} + +int +JLI_StrCCmp(const char *s1, const char* s2) +{ + return JLI_StrNCmp(s1, s2, JLI_StrLen(s2)); +} diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/jli_util.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/jli_util.h new file mode 100644 index 0000000..4335ba3 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/jli_util.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _JLI_UTIL_H +#define _JLI_UTIL_H + +#include +#include +#include +#include +#define JLDEBUG_ENV_ENTRY "_JAVA_LAUNCHER_DEBUG" + +void *JLI_MemAlloc(size_t size); +void *JLI_MemRealloc(void *ptr, size_t size); +char *JLI_StringDup(const char *s1); +void JLI_MemFree(void *ptr); +int JLI_StrCCmp(const char *s1, const char* s2); + +typedef struct { + char *arg; + jboolean has_wildcard; +} StdArg; + +StdArg *JLI_GetStdArgs(); +int JLI_GetStdArgc(); + +#define JLI_StrLen(p1) strlen((p1)) +#define JLI_StrChr(p1, p2) strchr((p1), (p2)) +#define JLI_StrRChr(p1, p2) strrchr((p1), (p2)) +#define JLI_StrCmp(p1, p2) strcmp((p1), (p2)) +#define JLI_StrNCmp(p1, p2, p3) strncmp((p1), (p2), (p3)) +#define JLI_StrCat(p1, p2) strcat((p1), (p2)) +#define JLI_StrCpy(p1, p2) strcpy((p1), (p2)) +#define JLI_StrNCpy(p1, p2, p3) strncpy((p1), (p2), (p3)) +#define JLI_StrStr(p1, p2) strstr((p1), (p2)) +#define JLI_StrSpn(p1, p2) strspn((p1), (p2)) +#define JLI_StrCSpn(p1, p2) strcspn((p1), (p2)) +#define JLI_StrPBrk(p1, p2) strpbrk((p1), (p2)) +#define JLI_StrTok(p1, p2) strtok((p1), (p2)) + +/* On Windows lseek() is in io.h rather than the location dictated by POSIX. */ +#ifdef _WIN32 +#include +#include +#include +#define JLI_StrCaseCmp(p1, p2) stricmp((p1), (p2)) +#define JLI_StrNCaseCmp(p1, p2, p3) strnicmp((p1), (p2), (p3)) +int JLI_Snprintf(char *buffer, size_t size, const char *format, ...); +void JLI_CmdToArgs(char *cmdline); +#define JLI_Lseek _lseeki64 +#define JLI_PutEnv _putenv +#define JLI_GetPid _getpid +#else /* NIXES */ +#include +#include +#define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2)) +#define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3)) +#define JLI_Snprintf snprintf +#define JLI_PutEnv putenv +#define JLI_GetPid getpid +#ifdef __solaris__ +#define JLI_Lseek llseek +#endif +#ifdef __linux__ +#define _LARGFILE64_SOURCE +#define JLI_Lseek lseek64 +#endif +#ifdef MACOSX +#define JLI_Lseek lseek +#endif +#ifdef _AIX +#define JLI_Lseek lseek +#endif +#endif /* _WIN32 */ + +/* + * Make launcher spit debug output. + */ +void JLI_TraceLauncher(const char* fmt, ...); +void JLI_SetTraceLauncher(); +jboolean JLI_IsTraceLauncher(); + +#endif /* _JLI_UTIL_H */ diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/main.c b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/main.c new file mode 100644 index 0000000..d05fff9 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/main.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + + +/* + * This file contains the main entry point into the launcher code + * this is the only file which will be repeatedly compiled by other + * tools. The rest of the files will be linked in. + */ + +#include "defines.h" + +#ifdef _MSC_VER +#if _MSC_VER > 1400 && _MSC_VER < 1600 + +/* + * When building for Microsoft Windows, main has a dependency on msvcr??.dll. + * + * When using Visual Studio 2005 or 2008, that must be recorded in + * the [java,javaw].exe.manifest file. + * + * As of VS2010 (ver=1600), the runtimes again no longer need manifests. + * + * Reference: + * C:/Program Files/Microsoft SDKs/Windows/v6.1/include/crtdefs.h + */ +#include +#ifdef _M_IX86 + +#pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='x86' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + +#endif /* _M_IX86 */ + +//This may not be necessary yet for the Windows 64-bit build, but it +//will be when that build environment is updated. Need to test to see +//if it is harmless: +#ifdef _M_AMD64 + +#pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='amd64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + +#endif /* _M_AMD64 */ +#endif /* _MSC_VER > 1400 && _MSC_VER < 1600 */ +#endif /* _MSC_VER */ + +/* + * Entry point. + */ +#ifdef JAVAW + +char **__initenv; + +int WINAPI +WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow) +{ + int margc; + char** margv; + const jboolean const_javaw = JNI_TRUE; + + __initenv = _environ; + +#else /* JAVAW */ +int +main(int argc, char **argv) +{ + int margc; + char** margv; + const jboolean const_javaw = JNI_FALSE; +#endif /* JAVAW */ +#ifdef _WIN32 + { + int i = 0; + if (getenv(JLDEBUG_ENV_ENTRY) != NULL) { + printf("Windows original main args:\n"); + for (i = 0 ; i < __argc ; i++) { + printf("wwwd_args[%d] = %s\n", i, __argv[i]); + } + } + } + JLI_CmdToArgs(GetCommandLine()); + margc = JLI_GetStdArgc(); + // add one more to mark the end + margv = (char **)JLI_MemAlloc((margc + 1) * (sizeof(char *))); + { + int i = 0; + StdArg *stdargs = JLI_GetStdArgs(); + for (i = 0 ; i < margc ; i++) { + margv[i] = stdargs[i].arg; + } + margv[i] = NULL; + } +#else /* *NIXES */ + margc = argc; + margv = argv; +#endif /* WIN32 */ + return JLI_Launch(margc, margv, + sizeof(const_jargs) / sizeof(char *), const_jargs, + sizeof(const_appclasspath) / sizeof(char *), const_appclasspath, + FULL_VERSION, + DOT_VERSION, + (const_progname != NULL) ? const_progname : *margv, + (const_launcher != NULL) ? const_launcher : *margv, + (const_jargs != NULL) ? JNI_TRUE : JNI_FALSE, + const_cpwildcard, const_javaw, const_ergo_class); +} diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/manifest_info.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/manifest_info.h new file mode 100644 index 0000000..8a4e824 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/manifest_info.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _MANIFEST_INFO_H +#define _MANIFEST_INFO_H + +#include + +/* + * Zip file header signatures + */ +#define SIGSIZ 4 /* size of all header signatures */ +#define LOCSIG 0x04034b50L /* "PK\003\004" */ +#define EXTSIG 0x08074b50L /* "PK\007\008" */ +#define CENSIG 0x02014b50L /* "PK\001\002" */ +#define ENDSIG 0x06054b50L /* "PK\005\006" */ + +#define ZIP64_ENDSIG 0x06064b50L /* "PK\006\006" */ +#define ZIP64_LOCSIG 0x07064b50L /* "PK\006\007" */ +/* + * Header sizes including signatures + */ +#define LOCHDR 30 +#define EXTHDR 16 +#define CENHDR 46 +#define ENDHDR 22 + +#define ZIP64_ENDHDR 56 // ZIP64 end header size +#define ZIP64_LOCHDR 20 // ZIP64 end loc header size +#define ZIP64_EXTHDR 24 // EXT header size +#define ZIP64_EXTID 1 // Extra field Zip64 header ID + +#define ZIP64_MAGICVAL 0xffffffffLL +#define ZIP64_MAGICCOUNT 0xffff + +/* + * Header field access macros + */ +#define CH(b, n) (((unsigned char *)(b))[n]) +#define SH(b, n) (CH(b, n) | (CH(b, n+1) << 8)) +#define LG(b, n) ((SH(b, n) | (SH(b, n+2) << 16)) &0xffffffffUL) +#define LL(b, n) (((jlong)LG(b, n)) | (((jlong)LG(b, n+4)) << 32)) +#define GETSIG(b) LG(b, 0) + +/* + * Macros for getting local file (LOC) header fields + */ +#define LOCVER(b) SH(b, 4) /* version needed to extract */ +#define LOCFLG(b) SH(b, 6) /* general purpose bit flags */ +#define LOCHOW(b) SH(b, 8) /* compression method */ +#define LOCTIM(b) LG(b, 10) /* modification time */ +#define LOCCRC(b) LG(b, 14) /* crc of uncompressed data */ +#define LOCSIZ(b) LG(b, 18) /* compressed data size */ +#define LOCLEN(b) LG(b, 22) /* uncompressed data size */ +#define LOCNAM(b) SH(b, 26) /* filename length */ +#define LOCEXT(b) SH(b, 28) /* extra field length */ + +/* + * Macros for getting extra local (EXT) header fields + */ +#define EXTCRC(b) LG(b, 4) /* crc of uncompressed data */ +#define EXTSIZ(b) LG(b, 8) /* compressed size */ +#define EXTLEN(b) LG(b, 12) /* uncompressed size */ + +/* + * Macros for getting central directory header (CEN) fields + */ +#define CENVEM(b) SH(b, 4) /* version made by */ +#define CENVER(b) SH(b, 6) /* version needed to extract */ +#define CENFLG(b) SH(b, 8) /* general purpose bit flags */ +#define CENHOW(b) SH(b, 10) /* compression method */ +#define CENTIM(b) LG(b, 12) /* modification time */ +#define CENCRC(b) LG(b, 16) /* crc of uncompressed data */ +#define CENSIZ(b) LG(b, 20) /* compressed size */ +#define CENLEN(b) LG(b, 24) /* uncompressed size */ +#define CENNAM(b) SH(b, 28) /* length of filename */ +#define CENEXT(b) SH(b, 30) /* length of extra field */ +#define CENCOM(b) SH(b, 32) /* file comment length */ +#define CENDSK(b) SH(b, 34) /* disk number start */ +#define CENATT(b) SH(b, 36) /* internal file attributes */ +#define CENATX(b) LG(b, 38) /* external file attributes */ +#define CENOFF(b) LG(b, 42) /* offset of local header */ + +/* + * Macros for getting end of central directory header (END) fields + */ +#define ENDSUB(b) SH(b, 8) /* number of entries on this disk */ +#define ENDTOT(b) SH(b, 10) /* total number of entries */ +#define ENDSIZ(b) LG(b, 12) /* central directory size */ +#define ENDOFF(b) LG(b, 16) /* central directory offset */ +#define ENDCOM(b) SH(b, 20) /* size of zip file comment */ + +/* + * Macros for getting Zip64 end of central directory header fields + */ +#define ZIP64_ENDLEN(b) LL(b, 4) /* size of zip64 end of central dir */ +#define ZIP64_ENDVEM(b) SH(b, 12) /* version made by */ +#define ZIP64_ENDVER(b) SH(b, 14) /* version needed to extract */ +#define ZIP64_ENDNMD(b) LG(b, 16) /* number of this disk */ +#define ZIP64_ENDDSK(b) LG(b, 20) /* disk number of start */ +#define ZIP64_ENDTOD(b) LL(b, 24) /* total number of entries on this disk */ +#define ZIP64_ENDTOT(b) LL(b, 32) /* total number of entries */ +#define ZIP64_ENDSIZ(b) LL(b, 40) /* central directory size in bytes */ +#define ZIP64_ENDOFF(b) LL(b, 48) /* offset of first CEN header */ + +/* + * Macros for getting Zip64 end of central directory locator fields + */ +#define ZIP64_LOCDSK(b) LG(b, 4) /* disk number start */ +#define ZIP64_LOCOFF(b) LL(b, 8) /* offset of zip64 end */ +#define ZIP64_LOCTOT(b) LG(b, 16) /* total number of disks */ + +/* + * A comment of maximum length of 64kb can follow the END record. This + * is the furthest the END record can be from the end of the file. + */ +#define END_MAXLEN (0xFFFF + ENDHDR) + +/* + * Supported compression methods. + */ +#define STORED 0 +#define DEFLATED 8 + +/* + * Information from the CEN entry to inflate a file. + */ +typedef struct zentry { /* Zip file entry */ + size_t isize; /* size of inflated data */ + size_t csize; /* size of compressed data (zero if uncompressed) */ + jlong offset; /* position of compressed data */ + int how; /* compression method (if any) */ +} zentry; + +/* + * Information returned from the Manifest file by the ParseManifest() routine. + * Certainly (much) more could be returned, but this is the information + * currently of interest to the C based Java utilities (particularly the + * Java launcher). + */ +typedef struct manifest_info { /* Interesting fields from the Manifest */ + char *manifest_version; /* Manifest-Version string */ + char *main_class; /* Main-Class entry */ + char *jre_version; /* Appropriate J2SE release spec */ + char jre_restrict_search; /* Restricted JRE search */ + char *splashscreen_image_file_name; /* splashscreen image file */ +} manifest_info; + +/* + * Attribute closure to provide to manifest_iterate. + */ +typedef void (*attribute_closure)(const char *name, const char *value, + void *user_data); + +/* + * Function prototypes. + */ +int JLI_ParseManifest(char *jarfile, manifest_info *info); +void *JLI_JarUnpackFile(const char *jarfile, const char *filename, + int *size); +void JLI_FreeManifest(void); +int JLI_ManifestIterate(const char *jarfile, attribute_closure ac, + void *user_data); + +#endif /* _MANIFEST_INFO_H */ diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/parse_manifest.c b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/parse_manifest.c new file mode 100644 index 0000000..130c4c3 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/parse_manifest.c @@ -0,0 +1,698 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#include +#include +#include +#include +#include +#include +#include "jli_util.h" + +#include +#include "manifest_info.h" + +static char *manifest; + +static const char *manifest_name = "META-INF/MANIFEST.MF"; + +/* + * Inflate the manifest file (or any file for that matter). + * + * fd: File descriptor of the jar file. + * entry: Contains the information necessary to perform the inflation + * (the compressed and uncompressed sizes and the offset in + * the file where the compressed data is located). + * size_out: Returns the size of the inflated file. + * + * Upon success, it returns a pointer to a NUL-terminated malloc'd buffer + * containing the inflated manifest file. When the caller is done with it, + * this buffer should be released by a call to free(). Upon failure, + * returns NULL. + */ +static char * +inflate_file(int fd, zentry *entry, int *size_out) +{ + char *in; + char *out; + z_stream zs; + + if (entry->csize == (size_t) -1 || entry->isize == (size_t) -1 ) + return (NULL); + if (JLI_Lseek(fd, entry->offset, SEEK_SET) < (jlong)0) + return (NULL); + if ((in = malloc(entry->csize + 1)) == NULL) + return (NULL); + if ((size_t)(read(fd, in, (unsigned int)entry->csize)) != entry->csize) { + free(in); + return (NULL); + } + if (entry->how == STORED) { + *(char *)((size_t)in + entry->csize) = '\0'; + if (size_out) { + *size_out = (int)entry->csize; + } + return (in); + } else if (entry->how == DEFLATED) { + zs.zalloc = (alloc_func)Z_NULL; + zs.zfree = (free_func)Z_NULL; + zs.opaque = (voidpf)Z_NULL; + zs.next_in = (Byte*)in; + zs.avail_in = (uInt)entry->csize; + if (inflateInit2(&zs, -MAX_WBITS) < 0) { + free(in); + return (NULL); + } + if ((out = malloc(entry->isize + 1)) == NULL) { + free(in); + return (NULL); + } + zs.next_out = (Byte*)out; + zs.avail_out = (uInt)entry->isize; + if (inflate(&zs, Z_PARTIAL_FLUSH) < 0) { + free(in); + free(out); + return (NULL); + } + *(char *)((size_t)out + entry->isize) = '\0'; + free(in); + if (inflateEnd(&zs) < 0) { + free(out); + return (NULL); + } + if (size_out) { + *size_out = (int)entry->isize; + } + return (out); + } + free(in); + return (NULL); +} + +static jboolean zip64_present = JNI_FALSE; + +/* + * Checks to see if we have ZIP64 archive, and save + * the check for later use + */ +static int +haveZIP64(Byte *p) { + jlong cenlen, cenoff, centot; + cenlen = ENDSIZ(p); + cenoff = ENDOFF(p); + centot = ENDTOT(p); + zip64_present = (cenlen == ZIP64_MAGICVAL || + cenoff == ZIP64_MAGICVAL || + centot == ZIP64_MAGICCOUNT); + return zip64_present; +} + +static jlong +find_end64(int fd, Byte *ep, jlong pos) +{ + jlong end64pos; + jlong bytes; + if ((end64pos = JLI_Lseek(fd, pos - ZIP64_LOCHDR, SEEK_SET)) < (jlong)0) + return -1; + if ((bytes = read(fd, ep, ZIP64_LOCHDR)) < 0) + return -1; + if (GETSIG(ep) == ZIP64_LOCSIG) + return end64pos; + return -1; +} + +/* + * A very little used routine to handle the case that zip file has + * a comment at the end. Believe it or not, the only way to find the + * END record is to walk backwards, byte by bloody byte looking for + * the END record signature. + * + * fd: File descriptor of the jar file. + * eb: Pointer to a buffer to receive a copy of the END header. + * + * Returns the offset of the END record in the file on success, + * -1 on failure. + */ +static jlong +find_end(int fd, Byte *eb) +{ + jlong len; + jlong pos; + jlong flen; + int bytes; + Byte *cp; + Byte *endpos; + Byte *buffer; + + /* + * 99.44% (or more) of the time, there will be no comment at the + * end of the zip file. Try reading just enough to read the END + * record from the end of the file, at this time we should also + * check to see if we have a ZIP64 archive. + */ + if ((pos = JLI_Lseek(fd, -ENDHDR, SEEK_END)) < (jlong)0) + return (-1); + if ((bytes = read(fd, eb, ENDHDR)) < 0) + return (-1); + if (GETSIG(eb) == ENDSIG) { + return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos; + } + + /* + * Shucky-Darn,... There is a comment at the end of the zip file. + * + * Allocate and fill a buffer with enough of the zip file + * to meet the specification for a maximal comment length. + */ + if ((flen = JLI_Lseek(fd, 0, SEEK_END)) < (jlong)0) + return (-1); + len = (flen < END_MAXLEN) ? flen : END_MAXLEN; + if (JLI_Lseek(fd, -len, SEEK_END) < (jlong)0) + return (-1); + if ((buffer = malloc(END_MAXLEN)) == NULL) + return (-1); + if ((bytes = read(fd, buffer, len)) < 0) { + free(buffer); + return (-1); + } + + /* + * Search backwards from the end of file stopping when the END header + * signature is found. (The first condition of the "if" is just a + * fast fail, because the GETSIG macro isn't always cheap. The + * final condition protects against false positives.) + */ + endpos = &buffer[bytes]; + for (cp = &buffer[bytes - ENDHDR]; cp >= &buffer[0]; cp--) + if ((*cp == (ENDSIG & 0xFF)) && (GETSIG(cp) == ENDSIG) && + (cp + ENDHDR + ENDCOM(cp) == endpos)) { + (void) memcpy(eb, cp, ENDHDR); + free(buffer); + pos = flen - (endpos - cp); + return haveZIP64(eb) ? find_end64(fd, eb, pos) : pos; + } + free(buffer); + return (-1); +} + +#define BUFSIZE (3 * 65536 + CENHDR + SIGSIZ) +#define MINREAD 1024 + +/* + * Computes and positions at the start of the CEN header, ie. the central + * directory, this will also return the offset if there is a zip file comment + * at the end of the archive, for most cases this would be 0. + */ +static jlong +compute_cen(int fd, Byte *bp) +{ + int bytes; + Byte *p; + jlong base_offset; + jlong offset; + char buffer[MINREAD]; + p = buffer; + /* + * Read the END Header, which is the starting point for ZIP files. + * (Clearly designed to make writing a zip file easier than reading + * one. Now isn't that precious...) + */ + if ((base_offset = find_end(fd, bp)) == -1) { + return (-1); + } + p = bp; + /* + * There is a historical, but undocumented, ability to allow for + * additional "stuff" to be prepended to the zip/jar file. It seems + * that this has been used to prepend an actual java launcher + * executable to the jar on Windows. Although this is just another + * form of statically linking a small piece of the JVM to the + * application, we choose to continue to support it. Note that no + * guarantees have been made (or should be made) to the customer that + * this will continue to work. + * + * Therefore, calculate the base offset of the zip file (within the + * expanded file) by assuming that the central directory is followed + * immediately by the end record. + */ + if (zip64_present) { + if ((offset = ZIP64_LOCOFF(p)) < (jlong)0) { + return -1; + } + if (JLI_Lseek(fd, offset, SEEK_SET) < (jlong) 0) { + return (-1); + } + if ((bytes = read(fd, buffer, MINREAD)) < 0) { + return (-1); + } + if (GETSIG(buffer) != ZIP64_ENDSIG) { + return -1; + } + if ((offset = ZIP64_ENDOFF(buffer)) < (jlong)0) { + return -1; + } + if (JLI_Lseek(fd, offset, SEEK_SET) < (jlong)0) { + return (-1); + } + p = buffer; + base_offset = base_offset - ZIP64_ENDSIZ(p) - ZIP64_ENDOFF(p) - ZIP64_ENDHDR; + } else { + base_offset = base_offset - ENDSIZ(p) - ENDOFF(p); + /* + * The END Header indicates the start of the Central Directory + * Headers. Remember that the desired Central Directory Header (CEN) + * will almost always be the second one and the first one is a small + * directory entry ("META-INF/"). Keep the code optimized for + * that case. + * + * Seek to the beginning of the Central Directory. + */ + if (JLI_Lseek(fd, base_offset + ENDOFF(p), SEEK_SET) < (jlong) 0) { + return (-1); + } + } + return base_offset; +} + +/* + * Locate the manifest file with the zip/jar file. + * + * fd: File descriptor of the jar file. + * entry: To be populated with the information necessary to perform + * the inflation (the compressed and uncompressed sizes and + * the offset in the file where the compressed data is located). + * + * Returns zero upon success. Returns a negative value upon failure. + * + * The buffer for reading the Central Directory if the zip/jar file needs + * to be large enough to accommodate the largest possible single record + * and the signature of the next record which is: + * + * 3*2**16 + CENHDR + SIGSIZ + * + * Each of the three variable sized fields (name, comment and extension) + * has a maximum possible size of 64k. + * + * Typically, only a small bit of this buffer is used with bytes shuffled + * down to the beginning of the buffer. It is one thing to allocate such + * a large buffer and another thing to actually start faulting it in. + * + * In most cases, all that needs to be read are the first two entries in + * a typical jar file (META-INF and META-INF/MANIFEST.MF). Keep this factoid + * in mind when optimizing this code. + */ +static int +find_file(int fd, zentry *entry, const char *file_name) +{ + int bytes; + int res; + int entry_size; + int read_size; + jlong base_offset; + Byte *p; + Byte *bp; + Byte *buffer; + Byte locbuf[LOCHDR]; + + if ((buffer = (Byte*)malloc(BUFSIZE)) == NULL) { + return(-1); + } + + bp = buffer; + base_offset = compute_cen(fd, bp); + if (base_offset == -1) { + free(buffer); + return -1; + } + + if ((bytes = read(fd, bp, MINREAD)) < 0) { + free(buffer); + return (-1); + } + p = bp; + /* + * Loop through the Central Directory Headers. Note that a valid zip/jar + * must have an ENDHDR (with ENDSIG) after the Central Directory. + */ + while (GETSIG(p) == CENSIG) { + + /* + * If a complete header isn't in the buffer, shift the contents + * of the buffer down and refill the buffer. Note that the check + * for "bytes < CENHDR" must be made before the test for the entire + * size of the header, because if bytes is less than CENHDR, the + * actual size of the header can't be determined. The addition of + * SIGSIZ guarantees that the next signature is also in the buffer + * for proper loop termination. + */ + if (bytes < CENHDR) { + p = memmove(bp, p, bytes); + if ((res = read(fd, bp + bytes, MINREAD)) <= 0) { + free(buffer); + return (-1); + } + bytes += res; + } + entry_size = CENHDR + CENNAM(p) + CENEXT(p) + CENCOM(p); + if (bytes < entry_size + SIGSIZ) { + if (p != bp) + p = memmove(bp, p, bytes); + read_size = entry_size - bytes + SIGSIZ; + read_size = (read_size < MINREAD) ? MINREAD : read_size; + if ((res = read(fd, bp + bytes, read_size)) <= 0) { + free(buffer); + return (-1); + } + bytes += res; + } + + /* + * Check if the name is the droid we are looking for; the jar file + * manifest. If so, build the entry record from the data found in + * the header located and return success. + */ + if ((size_t)CENNAM(p) == JLI_StrLen(file_name) && + memcmp((p + CENHDR), file_name, JLI_StrLen(file_name)) == 0) { + if (JLI_Lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (jlong)0) { + free(buffer); + return (-1); + } + if (read(fd, locbuf, LOCHDR) < 0) { + free(buffer); + return (-1); + } + if (GETSIG(locbuf) != LOCSIG) { + free(buffer); + return (-1); + } + entry->isize = CENLEN(p); + entry->csize = CENSIZ(p); + entry->offset = base_offset + CENOFF(p) + LOCHDR + + LOCNAM(locbuf) + LOCEXT(locbuf); + entry->how = CENHOW(p); + free(buffer); + return (0); + } + + /* + * Point to the next entry and decrement the count of valid remaining + * bytes. + */ + bytes -= entry_size; + p += entry_size; + } + free(buffer); + return (-1); /* Fell off the end the loop without a Manifest */ +} + +/* + * Parse a Manifest file header entry into a distinct "name" and "value". + * Continuation lines are joined into a single "value". The documented + * syntax for a header entry is: + * + * header: name ":" value + * + * name: alphanum *headerchar + * + * value: SPACE *otherchar newline *continuation + * + * continuation: SPACE *otherchar newline + * + * newline: CR LF | LF | CR (not followed by LF) + * + * alphanum: {"A"-"Z"} | {"a"-"z"} | {"0"-"9"} + * + * headerchar: alphanum | "-" | "_" + * + * otherchar: any UTF-8 character except NUL, CR and LF + * + * Note that a manifest file may be composed of multiple sections, + * each of which may contain multiple headers. + * + * section: *header +newline + * + * nonempty-section: +header +newline + * + * (Note that the point of "nonempty-section" is unclear, because it isn't + * referenced elsewhere in the full specification for the Manifest file.) + * + * Arguments: + * lp pointer to a character pointer which points to the start + * of a valid header. + * name pointer to a character pointer which will be set to point + * to the name portion of the header (nul terminated). + * value pointer to a character pointer which will be set to point + * to the value portion of the header (nul terminated). + * + * Returns: + * 1 Successful parsing of an NV pair. lp is updated to point to the + * next character after the terminating newline in the string + * representing the Manifest file. name and value are updated to + * point to the strings parsed. + * 0 A valid end of section indicator was encountered. lp, name, and + * value are not modified. + * -1 lp does not point to a valid header. Upon return, the values of + * lp, name, and value are undefined. + */ +static int +parse_nv_pair(char **lp, char **name, char **value) +{ + char *nl; + char *cp; + + /* + * End of the section - return 0. The end of section condition is + * indicated by either encountering a blank line or the end of the + * Manifest "string" (EOF). + */ + if (**lp == '\0' || **lp == '\n' || **lp == '\r') + return (0); + + /* + * Getting to here, indicates that *lp points to an "otherchar". + * Turn the "header" into a string on its own. + */ + nl = JLI_StrPBrk(*lp, "\n\r"); + if (nl == NULL) { + nl = JLI_StrChr(*lp, (int)'\0'); + } else { + cp = nl; /* For merging continuation lines */ + if (*nl == '\r' && *(nl+1) == '\n') + *nl++ = '\0'; + *nl++ = '\0'; + + /* + * Process any "continuation" line(s), by making them part of the + * "header" line. Yes, I know that we are "undoing" the NULs we + * just placed here, but continuation lines are the fairly rare + * case, so we shouldn't unnecessarily complicate the code above. + * + * Note that an entire continuation line is processed each iteration + * through the outer while loop. + */ + while (*nl == ' ') { + nl++; /* First character to be moved */ + while (*nl != '\n' && *nl != '\r' && *nl != '\0') + *cp++ = *nl++; /* Shift string */ + if (*nl == '\0') + return (-1); /* Error: newline required */ + *cp = '\0'; + if (*nl == '\r' && *(nl+1) == '\n') + *nl++ = '\0'; + *nl++ = '\0'; + } + } + + /* + * Separate the name from the value; + */ + cp = JLI_StrChr(*lp, (int)':'); + if (cp == NULL) + return (-1); + *cp++ = '\0'; /* The colon terminates the name */ + if (*cp != ' ') + return (-1); + *cp++ = '\0'; /* Eat the required space */ + *name = *lp; + *value = cp; + *lp = nl; + return (1); +} + +/* + * Read the manifest from the specified jar file and fill in the manifest_info + * structure with the information found within. + * + * Error returns are as follows: + * 0 Success + * -1 Unable to open jarfile + * -2 Error accessing the manifest from within the jarfile (most likely + * a manifest is not present, or this isn't a valid zip/jar file). + */ +int +JLI_ParseManifest(char *jarfile, manifest_info *info) +{ + int fd; + zentry entry; + char *lp; + char *name; + char *value; + int rc; + char *splashscreen_name = NULL; + + if ((fd = open(jarfile, O_RDONLY +#ifdef O_LARGEFILE + | O_LARGEFILE /* large file mode */ +#endif +#ifdef O_BINARY + | O_BINARY /* use binary mode on windows */ +#endif + )) == -1) { + return (-1); + } + info->manifest_version = NULL; + info->main_class = NULL; + info->jre_version = NULL; + info->jre_restrict_search = 0; + info->splashscreen_image_file_name = NULL; + if (rc = find_file(fd, &entry, manifest_name) != 0) { + close(fd); + return (-2); + } + manifest = inflate_file(fd, &entry, NULL); + if (manifest == NULL) { + close(fd); + return (-2); + } + lp = manifest; + while ((rc = parse_nv_pair(&lp, &name, &value)) > 0) { + if (JLI_StrCaseCmp(name, "Manifest-Version") == 0) + info->manifest_version = value; + else if (JLI_StrCaseCmp(name, "Main-Class") == 0) + info->main_class = value; + else if (JLI_StrCaseCmp(name, "JRE-Version") == 0) + info->jre_version = value; + else if (JLI_StrCaseCmp(name, "JRE-Restrict-Search") == 0) { + if (JLI_StrCaseCmp(value, "true") == 0) + info->jre_restrict_search = 1; + } else if (JLI_StrCaseCmp(name, "Splashscreen-Image") == 0) { + info->splashscreen_image_file_name = value; + } + } + close(fd); + if (rc == 0) + return (0); + else + return (-2); +} + +/* + * Opens the jar file and unpacks the specified file from its contents. + * Returns NULL on failure. + */ +void * +JLI_JarUnpackFile(const char *jarfile, const char *filename, int *size) { + int fd; + zentry entry; + void *data = NULL; + + if ((fd = open(jarfile, O_RDONLY +#ifdef O_LARGEFILE + | O_LARGEFILE /* large file mode */ +#endif +#ifdef O_BINARY + | O_BINARY /* use binary mode on windows */ +#endif + )) == -1) { + return NULL; + } + if (find_file(fd, &entry, filename) == 0) { + data = inflate_file(fd, &entry, size); + } + close(fd); + return (data); +} + +/* + * Specialized "free" function. + */ +void +JLI_FreeManifest() +{ + if (manifest) + free(manifest); +} + +/* + * Iterate over the manifest of the specified jar file and invoke the provided + * closure function for each attribute encountered. + * + * Error returns are as follows: + * 0 Success + * -1 Unable to open jarfile + * -2 Error accessing the manifest from within the jarfile (most likely + * this means a manifest is not present, or it isn't a valid zip/jar file). + */ +int +JLI_ManifestIterate(const char *jarfile, attribute_closure ac, void *user_data) +{ + int fd; + zentry entry; + char *mp; /* manifest pointer */ + char *lp; /* pointer into manifest, updated during iteration */ + char *name; + char *value; + int rc; + + if ((fd = open(jarfile, O_RDONLY +#ifdef O_LARGEFILE + | O_LARGEFILE /* large file mode */ +#endif +#ifdef O_BINARY + | O_BINARY /* use binary mode on windows */ +#endif + )) == -1) { + return (-1); + } + + if (rc = find_file(fd, &entry, manifest_name) != 0) { + close(fd); + return (-2); + } + + mp = inflate_file(fd, &entry, NULL); + if (mp == NULL) { + close(fd); + return (-2); + } + + lp = mp; + while ((rc = parse_nv_pair(&lp, &name, &value)) > 0) { + (*ac)(name, value, user_data); + } + free(mp); + close(fd); + return (rc == 0) ? 0 : -2; +} diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/splashscreen.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/splashscreen.h new file mode 100644 index 0000000..ff3b402 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/splashscreen.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + + +int DoSplashLoadMemory(void* pdata, int size); /* requires preloading the file */ +int DoSplashLoadFile(const char* filename); +void DoSplashInit(void); +void DoSplashClose(void); +void DoSplashSetFileJarName(const char* fileName, const char* jarName); +void DoSplashSetScaleFactor(float scaleFactor); +char* DoSplashGetScaledImageName(const char* jarName, const char* fileName, + float* scaleFactor); diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/splashscreen_stubs.c b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/splashscreen_stubs.c new file mode 100644 index 0000000..15b2e62 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/splashscreen_stubs.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#include +#include "splashscreen.h" + +extern void* SplashProcAddress(const char* name); /* in java_md.c */ + +/* + * Prototypes of pointers to functions in splashscreen shared lib + */ +typedef int (*SplashLoadMemory_t)(void* pdata, int size); +typedef int (*SplashLoadFile_t)(const char* filename); +typedef void (*SplashInit_t)(void); +typedef void (*SplashClose_t)(void); +typedef void (*SplashSetFileJarName_t)(const char* fileName, + const char* jarName); +typedef void (*SplashSetScaleFactor_t)(float scaleFactor); +typedef char* (*SplashGetScaledImageName_t)(const char* fileName, + const char* jarName, float* scaleFactor); + +/* + * This macro invokes a function from the shared lib. + * it locates a function with SplashProcAddress on demand. + * if SplashProcAddress fails, def value is returned. + * + * it is further wrapped with INVOKEV (works with functions which return + * void and INVOKE (for all other functions). INVOKEV looks a bit ugly, + * that's due being unable to return a value of type void in C. INVOKEV + * works around this by using semicolon instead of return operator. + */ +#define _INVOKE(name,def,ret) \ + static void* proc = NULL; \ + if (!proc) { proc = SplashProcAddress(#name); } \ + if (!proc) { return def; } \ + ret ((name##_t)proc) + +#define INVOKE(name,def) _INVOKE(name,def,return) +#define INVOKEV(name) _INVOKE(name, ,;) + +int DoSplashLoadMemory(void* pdata, int size) { + INVOKE(SplashLoadMemory, NULL)(pdata, size); +} + +int DoSplashLoadFile(const char* filename) { + INVOKE(SplashLoadFile, NULL)(filename); +} + +void DoSplashInit(void) { + INVOKEV(SplashInit)(); +} + +void DoSplashClose(void) { + INVOKEV(SplashClose)(); +} + +void DoSplashSetFileJarName(const char* fileName, const char* jarName) { + INVOKEV(SplashSetFileJarName)(fileName, jarName); +} + +void DoSplashSetScaleFactor(float scaleFactor) { + INVOKEV(SplashSetScaleFactor)(scaleFactor); +} + +char* DoSplashGetScaledImageName(const char* fileName, const char* jarName, + float* scaleFactor) { + INVOKE(SplashGetScaledImageName, NULL)(fileName, jarName, scaleFactor); +} \ No newline at end of file diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/version_comp.c b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/version_comp.c new file mode 100644 index 0000000..d688796 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/version_comp.c @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#include +#include +#include +#include +#include "jni.h" +#include "jli_util.h" +#include "version_comp.h" + +/* + * A collection of useful strings. One should think of these as #define + * entries, but actual strings can be more efficient (with many compilers). + */ +static const char *separators = ".-_"; +static const char *zero_string = "0"; + +/* + * Validate a string as parsable as a "Java int". If so parsable, + * return true (non-zero) and store the numeric value at the address + * passed in as "value"; otherwise return false (zero). + * + * Note that the maximum allowable value is 2147483647 as defined by + * the "Java Language Specification" which precludes the use of native + * conversion routines which may have other limits. + * + * Also note that we don't have to worry about the alternate maximum + * allowable value of 2147483648 because it is only allowed after + * the unary negation operator and this grammar doesn't have one + * of those. + * + * Finally, note that a value which exceeds the maximum jint value will + * return false (zero). This results in the otherwise purely numeric + * string being compared as a string of characters (as per the spec.) + */ +static int +isjavaint(const char *s, jint *value) +{ + jlong sum = 0; + jint digit; + while (*s != '\0') + if (isdigit(*s)) { + digit = (jint)((int)(*s++) - (int)('0')); + sum = (sum * 10) + digit; + if (sum > 2147483647) + return (0); /* Overflows jint (but not jlong) */ + } else + return (0); + *value = (jint)sum; + return (1); +} + +/* + * Modeled after strcmp(), compare two strings (as in the grammar defined + * in Appendix A of JSR 56). If both strings can be interpreted as + * Java ints, do a numeric comparison, else it is strcmp(). + */ +static int +comp_string(const char *s1, const char *s2) +{ + jint v1, v2; + if (isjavaint(s1, &v1) && isjavaint(s2, &v2)) + return ((int)(v1 - v2)); + else + return (JLI_StrCmp(s1, s2)); +} + +/* + * Modeled after strcmp(), compare two version-ids for a Prefix + * Match as defined in JSR 56. + */ +int +JLI_PrefixVersionId(const char *id1, char *id2) +{ + char *s1 = JLI_StringDup(id1); + char *s2 = JLI_StringDup(id2); + char *m1 = s1; + char *m2 = s2; + char *end1 = NULL; + char *end2 = NULL; + int res = 0; + + do { + + if ((s1 != NULL) && ((end1 = JLI_StrPBrk(s1, ".-_")) != NULL)) + *end1 = '\0'; + if ((s2 != NULL) && ((end2 = JLI_StrPBrk(s2, ".-_")) != NULL)) + *end2 = '\0'; + + res = comp_string(s1, s2); + + if (end1 != NULL) + s1 = end1 + 1; + else + s1 = NULL; + if (end2 != NULL) + s2 = end2 + 1; + else + s2 = NULL; + + } while (res == 0 && ((s1 != NULL) && (s2 != NULL))); + + JLI_MemFree(m1); + JLI_MemFree(m2); + return (res); +} + +/* + * Modeled after strcmp(), compare two version-ids for an Exact + * Match as defined in JSR 56. + */ +int +JLI_ExactVersionId(const char *id1, char *id2) +{ + char *s1 = JLI_StringDup(id1); + char *s2 = JLI_StringDup(id2); + char *m1 = s1; + char *m2 = s2; + char *end1 = NULL; + char *end2 = NULL; + int res = 0; + + do { + + if ((s1 != NULL) && ((end1 = JLI_StrPBrk(s1, separators)) != NULL)) + *end1 = '\0'; + if ((s2 != NULL) && ((end2 = JLI_StrPBrk(s2, separators)) != NULL)) + *end2 = '\0'; + + if ((s1 != NULL) && (s2 == NULL)) + res = comp_string(s1, zero_string); + else if ((s1 == NULL) && (s2 != NULL)) + res = comp_string(zero_string, s2); + else + res = comp_string(s1, s2); + + if (end1 != NULL) + s1 = end1 + 1; + else + s1 = NULL; + if (end2 != NULL) + s2 = end2 + 1; + else + s2 = NULL; + + } while (res == 0 && ((s1 != NULL) || (s2 != NULL))); + + JLI_MemFree(m1); + JLI_MemFree(m2); + return (res); +} + +/* + * Return true if this simple-element (as defined in JSR 56) forms + * an acceptable match. + * + * JSR 56 is modified by the Java Web Start Developer Guide + * where it is stated "... Java Web Start will not consider an installed + * non-FCS (i.e., milestone) JRE as a match. ... a JRE from Sun + * Microsystems, Inc., is by convention a non-FCS (milestone) JRE + * if there is a dash (-) in the version string." + * + * An undocumented caveat to the above is that an exact match with a + * hyphen is accepted as a development extension. + * + * These modifications are addressed by the specific comparisons + * for releases with hyphens. + */ +static int +acceptable_simple_element(const char *release, char *simple_element) +{ + char *modifier; + modifier = simple_element + JLI_StrLen(simple_element) - 1; + if (*modifier == '*') { + *modifier = '\0'; + if (JLI_StrChr(release, '-')) + return ((JLI_StrCmp(release, simple_element) == 0)?1:0); + return ((JLI_PrefixVersionId(release, simple_element) == 0)?1:0); + } else if (*modifier == '+') { + *modifier = '\0'; + if (JLI_StrChr(release, '-')) + return ((JLI_StrCmp(release, simple_element) == 0)?1:0); + return ((JLI_ExactVersionId(release, simple_element) >= 0)?1:0); + } else { + return ((JLI_ExactVersionId(release, simple_element) == 0)?1:0); + } +} + +/* + * Return true if this element (as defined in JSR 56) forms + * an acceptable match. An element is the intersection (and) + * of multiple simple-elements. + */ +static int +acceptable_element(const char *release, char *element) +{ + char *end; + do { + if ((end = JLI_StrChr(element, '&')) != NULL) + *end = '\0'; + if (!acceptable_simple_element(release, element)) + return (0); + if (end != NULL) + element = end + 1; + } while (end != NULL); + return (1); +} + +/* + * Checks if release is acceptable by the specification version-string. + * Return true if this version-string (as defined in JSR 56) forms + * an acceptable match. A version-string is the union (or) of multiple + * elements. + */ +int +JLI_AcceptableRelease(const char *release, char *version_string) +{ + char *vs; + char *m1; + char *end; + m1 = vs = JLI_StringDup(version_string); + do { + if ((end = JLI_StrChr(vs, ' ')) != NULL) + *end = '\0'; + if (acceptable_element(release, vs)) { + JLI_MemFree(m1); + return (1); + } + if (end != NULL) + vs = end + 1; + } while (end != NULL); + JLI_MemFree(m1); + return (0); +} + +/* + * Return true if this is a valid simple-element (as defined in JSR 56). + * + * The official grammar for a simple-element is: + * + * simple-element ::= version-id | version-id modifier + * modifier ::= '+' | '*' + * version-id ::= string ( separator string )* + * string ::= char ( char )* + * char ::= Any ASCII character except a space, an + * ampersand, a separator or a modifier + * separator ::= '.' | '-' | '_' + * + * However, for efficiency, it is time to abandon the top down parser + * implementation. After deleting the potential trailing modifier, we + * are left with a version-id. + * + * Note that a valid version-id has three simple properties: + * + * 1) Doesn't contain a space, an ampersand or a modifier. + * + * 2) Doesn't begin or end with a separator. + * + * 3) Doesn't contain two adjacent separators. + * + * Any other line noise constitutes a valid version-id. + */ +static int +valid_simple_element(char *simple_element) +{ + char *last; + size_t len; + + if ((simple_element == NULL) || ((len = JLI_StrLen(simple_element)) == 0)) + return (0); + last = simple_element + len - 1; + if (*last == '*' || *last == '+') { + if (--len == 0) + return (0); + *last-- = '\0'; + } + if (JLI_StrPBrk(simple_element, " &+*") != NULL) /* Property #1 */ + return (0); + if ((JLI_StrChr(".-_", *simple_element) != NULL) || /* Property #2 */ + (JLI_StrChr(".-_", *last) != NULL)) + return (0); + for (; simple_element != last; simple_element++) /* Property #3 */ + if ((JLI_StrChr(".-_", *simple_element) != NULL) && + (JLI_StrChr(".-_", *(simple_element + 1)) != NULL)) + return (0); + return (1); +} + +/* + * Return true if this is a valid element (as defined in JSR 56). + * An element is the intersection (and) of multiple simple-elements. + */ +static int +valid_element(char *element) +{ + char *end; + if ((element == NULL) || (JLI_StrLen(element) == 0)) + return (0); + do { + if ((end = JLI_StrChr(element, '&')) != NULL) + *end = '\0'; + if (!valid_simple_element(element)) + return (0); + if (end != NULL) + element = end + 1; + } while (end != NULL); + return (1); +} + +/* + * Validates a version string by the extended JSR 56 grammar. + */ +int +JLI_ValidVersionString(char *version_string) +{ + char *vs; + char *m1; + char *end; + if ((version_string == NULL) || (JLI_StrLen(version_string) == 0)) + return (0); + m1 = vs = JLI_StringDup(version_string); + do { + if ((end = JLI_StrChr(vs, ' ')) != NULL) + *end = '\0'; + if (!valid_element(vs)) { + JLI_MemFree(m1); + return (0); + } + if (end != NULL) + vs = end + 1; + } while (end != NULL); + JLI_MemFree(m1); + return (1); +} diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/version_comp.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/version_comp.h new file mode 100644 index 0000000..f50ab34 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/version_comp.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef _VERSION_COMP_H +#define _VERSION_COMP_H + +/* + * Function prototypes. + */ +int JLI_ExactVersionId(const char *id1, char *id2); +int JLI_PrefixVersionId(const char *id1, char *id2); +int JLI_AcceptableRelease(const char *release, char *version_string); +int JLI_ValidVersionString(char *version_string); + +#endif /* _VERSION_COMP_H */ diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/wildcard.c b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/wildcard.c new file mode 100644 index 0000000..c3dc646 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/wildcard.c @@ -0,0 +1,501 @@ +/* + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +/* + * Class-Path Wildcards + * + * The syntax for wildcards is a single asterisk. The class path + * foo/"*", e.g., loads all jar files in the directory named foo. + * (This requires careful quotation when used in shell scripts.) + * + * Only files whose names end in .jar or .JAR are matched. + * Files whose names end in .zip, or which have a particular + * magic number, regardless of filename extension, are not + * matched. + * + * Files are considered regardless of whether or not they are + * "hidden" in the UNIX sense, i.e., have names beginning with '.'. + * + * A wildcard only matches jar files, not class files in the same + * directory. If you want to load both class files and jar files from + * a single directory foo then you can say foo:foo/"*", or foo/"*":foo + * if you want the jar files to take precedence. + * + * Subdirectories are not searched recursively, i.e., foo/"*" only + * looks for jar files in foo, not in foo/bar, foo/baz, etc. + * + * Expansion of wildcards is done early, prior to the invocation of a + * program's main method, rather than late, during the class-loading + * process itself. Each element of the input class path containing a + * wildcard is replaced by the (possibly empty) sequence of elements + * generated by enumerating the jar files in the named directory. If + * the directory foo contains a.jar, b.jar, and c.jar, + * e.g., then the class path foo/"*" is expanded into + * foo/a.jar:foo/b.jar:foo/c.jar, and that string would be the value + * of the system property java.class.path. + * + * The order in which the jar files in a directory are enumerated in + * the expanded class path is not specified and may vary from platform + * to platform and even from moment to moment on the same machine. A + * well-constructed application should not depend upon any particular + * order. If a specific order is required then the jar files can be + * enumerated explicitly in the class path. + * + * The CLASSPATH environment variable is not treated any differently + * from the -classpath (equiv. -cp) command-line option, + * i.e. wildcards are honored in all these cases. + * + * Class-path wildcards are not honored in the Class-Path jar-manifest + * header. + * + * Class-path wildcards are honored not only by the Java launcher but + * also by most other command-line tools that accept class paths, and + * in particular by javac and javadoc. + * + * Class-path wildcards are not honored in any other kind of path, and + * especially not in the bootstrap class path, which is a mere + * artifact of our implementation and not something that developers + * should use. + * + * Classpath wildcards are only expanded in the Java launcher code, + * supporting the use of wildcards on the command line and in the + * CLASSPATH environment variable. We do not support the use of + * wildcards by applications that embed the JVM. + */ + +#include +#include +#include +#include +#include +#include "java.h" /* Strictly for PATH_SEPARATOR/FILE_SEPARATOR */ +#include "jli_util.h" + +#ifdef _WIN32 +#include +#else /* Unix */ +#include +#include +#endif /* Unix */ + +static int +exists(const char* filename) +{ +#ifdef _WIN32 + return _access(filename, 0) == 0; +#else + return access(filename, F_OK) == 0; +#endif +} + +#define NEW_(TYPE) ((TYPE) JLI_MemAlloc(sizeof(struct TYPE##_))) + +/* + * Wildcard directory iteration. + * WildcardIterator_for(wildcard) returns an iterator. + * Each call to that iterator's next() method returns the basename + * of an entry in the wildcard's directory. The basename's memory + * belongs to the iterator. The caller is responsible for prepending + * the directory name and file separator, if necessary. + * When done with the iterator, call the close method to clean up. + */ +typedef struct WildcardIterator_* WildcardIterator; + +#ifdef _WIN32 +struct WildcardIterator_ +{ + HANDLE handle; + char *firstFile; /* Stupid FindFirstFile...FindNextFile */ +}; +// since this is used repeatedly we keep it here. +static WIN32_FIND_DATA find_data; +static WildcardIterator +WildcardIterator_for(const char *wildcard) +{ + WildcardIterator it = NEW_(WildcardIterator); + HANDLE handle = FindFirstFile(wildcard, &find_data); + if (handle == INVALID_HANDLE_VALUE) { + JLI_MemFree(it); + return NULL; + } + it->handle = handle; + it->firstFile = find_data.cFileName; + return it; +} + +static char * +WildcardIterator_next(WildcardIterator it) +{ + if (it->firstFile != NULL) { + char *firstFile = it->firstFile; + it->firstFile = NULL; + return firstFile; + } + return FindNextFile(it->handle, &find_data) + ? find_data.cFileName : NULL; +} + +static void +WildcardIterator_close(WildcardIterator it) +{ + if (it) { + FindClose(it->handle); + JLI_MemFree(it->firstFile); + JLI_MemFree(it); + } +} + +#else /* Unix */ +struct WildcardIterator_ +{ + DIR *dir; +}; + +static WildcardIterator +WildcardIterator_for(const char *wildcard) +{ + DIR *dir; + int wildlen = JLI_StrLen(wildcard); + if (wildlen < 2) { + dir = opendir("."); + } else { + char *dirname = JLI_StringDup(wildcard); + dirname[wildlen - 1] = '\0'; + dir = opendir(dirname); + JLI_MemFree(dirname); + } + if (dir == NULL) + return NULL; + else { + WildcardIterator it = NEW_(WildcardIterator); + it->dir = dir; + return it; + } +} + +static char * +WildcardIterator_next(WildcardIterator it) +{ + struct dirent* dirp = readdir(it->dir); + return dirp ? dirp->d_name : NULL; +} + +static void +WildcardIterator_close(WildcardIterator it) +{ + if (it) { + closedir(it->dir); + JLI_MemFree(it); + } +} +#endif /* Unix */ + +static int +equal(const char *s1, const char *s2) +{ + return JLI_StrCmp(s1, s2) == 0; +} + +/* + * FileList ADT - a dynamic list of C filenames + */ +struct FileList_ +{ + char **files; + int size; + int capacity; +}; +typedef struct FileList_ *FileList; + +static FileList +FileList_new(int capacity) +{ + FileList fl = NEW_(FileList); + fl->capacity = capacity; + fl->files = (char **) JLI_MemAlloc(capacity * sizeof(fl->files[0])); + fl->size = 0; + return fl; +} + + + +static void +FileList_free(FileList fl) +{ + if (fl) { + if (fl->files) { + int i; + for (i = 0; i < fl->size; i++) + JLI_MemFree(fl->files[i]); + JLI_MemFree(fl->files); + } + JLI_MemFree(fl); + } +} + +static void +FileList_ensureCapacity(FileList fl, int capacity) +{ + if (fl->capacity < capacity) { + while (fl->capacity < capacity) + fl->capacity *= 2; + fl->files = JLI_MemRealloc(fl->files, + fl->capacity * sizeof(fl->files[0])); + } +} + +static void +FileList_add(FileList fl, char *file) +{ + FileList_ensureCapacity(fl, fl->size+1); + fl->files[fl->size++] = file; +} + +static void +FileList_addSubstring(FileList fl, const char *beg, int len) +{ + char *filename = (char *) JLI_MemAlloc(len+1); + memcpy(filename, beg, len); + filename[len] = '\0'; + FileList_ensureCapacity(fl, fl->size+1); + fl->files[fl->size++] = filename; +} + +static char * +FileList_join(FileList fl, char sep) +{ + int i; + int size; + char *path; + char *p; + for (i = 0, size = 1; i < fl->size; i++) + size += (int)JLI_StrLen(fl->files[i]) + 1; + + path = JLI_MemAlloc(size); + + for (i = 0, p = path; i < fl->size; i++) { + int len = (int)JLI_StrLen(fl->files[i]); + if (i > 0) *p++ = sep; + memcpy(p, fl->files[i], len); + p += len; + } + *p = '\0'; + + return path; +} + +static FileList +FileList_split(const char *path, char sep) +{ + const char *p, *q; + int len = (int)JLI_StrLen(path); + int count; + FileList fl; + for (count = 1, p = path; p < path + len; p++) + count += (*p == sep); + fl = FileList_new(count); + for (p = path;;) { + for (q = p; q <= path + len; q++) { + if (*q == sep || *q == '\0') { + FileList_addSubstring(fl, p, q - p); + if (*q == '\0') + return fl; + p = q + 1; + } + } + } +} + +static int +isJarFileName(const char *filename) +{ + int len = (int)JLI_StrLen(filename); + return (len >= 4) && + (filename[len - 4] == '.') && + (equal(filename + len - 3, "jar") || + equal(filename + len - 3, "JAR")) && + /* Paranoia: Maybe filename is "DIR:foo.jar" */ + (JLI_StrChr(filename, PATH_SEPARATOR) == NULL); +} + +static char * +wildcardConcat(const char *wildcard, const char *basename) +{ + int wildlen = (int)JLI_StrLen(wildcard); + int baselen = (int)JLI_StrLen(basename); + char *filename = (char *) JLI_MemAlloc(wildlen + baselen); + /* Replace the trailing '*' with basename */ + memcpy(filename, wildcard, wildlen-1); + memcpy(filename+wildlen-1, basename, baselen+1); + return filename; +} + +static FileList +wildcardFileList(const char *wildcard) +{ + const char *basename; + FileList fl = FileList_new(16); + WildcardIterator it = WildcardIterator_for(wildcard); + + if (it == NULL) + { + FileList_free(fl); + return NULL; + } + + while ((basename = WildcardIterator_next(it)) != NULL) + if (isJarFileName(basename)) + FileList_add(fl, wildcardConcat(wildcard, basename)); + WildcardIterator_close(it); + return fl; +} + +static int +isWildcard(const char *filename) +{ + int len = (int)JLI_StrLen(filename); + return (len > 0) && + (filename[len - 1] == '*') && + (len == 1 || IS_FILE_SEPARATOR(filename[len - 2])) && + (! exists(filename)); +} + +static void +FileList_expandWildcards(FileList fl) +{ + int i, j; + for (i = 0; i < fl->size; i++) { + if (isWildcard(fl->files[i])) { + FileList expanded = wildcardFileList(fl->files[i]); + if (expanded != NULL && expanded->size > 0) { + JLI_MemFree(fl->files[i]); + FileList_ensureCapacity(fl, fl->size + expanded->size); + for (j = fl->size - 1; j >= i+1; j--) + fl->files[j+expanded->size-1] = fl->files[j]; + for (j = 0; j < expanded->size; j++) + fl->files[i+j] = expanded->files[j]; + i += expanded->size - 1; + fl->size += expanded->size - 1; + /* fl expropriates expanded's elements. */ + expanded->size = 0; + } + FileList_free(expanded); + } + } +} + +const char * +JLI_WildcardExpandClasspath(const char *classpath) +{ + char *expanded; + FileList fl; + + if (JLI_StrChr(classpath, '*') == NULL) + return classpath; + fl = FileList_split(classpath, PATH_SEPARATOR); + FileList_expandWildcards(fl); + expanded = FileList_join(fl, PATH_SEPARATOR); + FileList_free(fl); + if (getenv(JLDEBUG_ENV_ENTRY) != 0) + printf("Expanded wildcards:\n" + " before: \"%s\"\n" + " after : \"%s\"\n", + classpath, expanded); + return expanded; +} + +#ifdef DEBUG_WILDCARD +static void +FileList_print(FileList fl) +{ + int i; + putchar('['); + for (i = 0; i < fl->size; i++) { + if (i > 0) printf(", "); + printf("\"%s\"",fl->files[i]); + } + putchar(']'); +} + +static void +wildcardExpandArgv(const char ***argv) +{ + int i; + for (i = 0; (*argv)[i]; i++) { + if (equal((*argv)[i], "-cp") || + equal((*argv)[i], "-classpath")) { + i++; + (*argv)[i] = wildcardExpandClasspath((*argv)[i]); + } + } +} + +static void +debugPrintArgv(char *argv[]) +{ + int i; + putchar('['); + for (i = 0; argv[i]; i++) { + if (i > 0) printf(", "); + printf("\"%s\"", argv[i]); + } + printf("]\n"); +} + +int +main(int argc, char *argv[]) +{ + argv[0] = "java"; + wildcardExpandArgv((const char***)&argv); + debugPrintArgv(argv); + /* execvp("java", argv); */ + return 0; +} +#endif /* DEBUG_WILDCARD */ + +/* Cute little perl prototype implementation.... + +my $sep = ($^O =~ /^(Windows|cygwin)/) ? ";" : ":"; + +sub expand($) { + opendir DIR, $_[0] or return $_[0]; + join $sep, map {"$_[0]/$_"} grep {/\.(jar|JAR)$/} readdir DIR; +} + +sub munge($) { + join $sep, + map {(! -r $_ and s/[\/\\]+\*$//) ? expand $_ : $_} split $sep, $_[0]; +} + +for (my $i = 0; $i < @ARGV - 1; $i++) { + $ARGV[$i+1] = munge $ARGV[$i+1] if $ARGV[$i] =~ /^-c(p|lasspath)$/; +} + +$ENV{CLASSPATH} = munge $ENV{CLASSPATH} if exists $ENV{CLASSPATH}; +@ARGV = ("java", @ARGV); +print "@ARGV\n"; +exec @ARGV; + +*/ diff --git a/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/wildcard.h b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/wildcard.h new file mode 100644 index 0000000..1f1aba9 --- /dev/null +++ b/SearchFramework1.0.1/out/production/jdk1.8.0_131/launcher/wildcard.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ + +#ifndef WILDCARD_H_ +#define WILDCARD_H_ + +const char *JLI_WildcardExpandClasspath(const char *classpath); + +#endif /* include guard */ diff --git a/SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFeederTest.class b/SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFeederTest.class new file mode 100644 index 0000000000000000000000000000000000000000..147bdfc07d0f4ba7edc4305f0d71f237b4b150c6 GIT binary patch literal 1271 zcmZ`(T~pIQ6g}G}-I@l00)+x9f?)ZKA4LTUijK@MQ;-pd5#N?Jlwe6Z=|ca627C}8%9m;Idz8H#lyg=`5tW?ST!N{b{)6uxD{)I)+@GMrYLq@E-<7j zw%mw-wLmKNqFSlv ztw1_eYtOYoZo5 ziQ@ssLykub*_VMUodbKzsXNrFW!LqjkdEgPtHGk@SFHVjw4kx(NGej)9IMecW77-# zlD*<6DY}~5I-}|_(T)y=8`o*2JVFgrU2YS|*kih0#kWG?QlN2xX`WIwmi6_U#hs))$6tAu-k5LNq#*|E#OjF(Eyl z1kOc*g`qd4PX}>99qqB)f5&3Hm9XltsP0FxGP#SO^BjcXd!oK>9};Q0H*e_PxZz9p zIsQUjgx1Qwc#k2p(M46i82w2vFm%$&qM6aGPn>{#3b)fVCPJf$E?S!r0Nv=JH;^bD z6ht}yK%9`k;wfU=Cx{nMp>3!26C~Cqr;fqbr;m}G*RtAYTw(ZtUbQk9z9BWQXZ2&4 zAJ2ZOq#9Jx>)gDvO-C>7=_+-DRuZ#>>?f*eOk#l0 zF+z;u8byuc1|d}$k!6T1H_0-9*col>9BmxK92&<6r|%Sgk=rN%R2Rl*rmqZ*G35RL Dp2;@_ literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFindingTest.class b/SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/problem/pathfinding/PathFindingTest.class new file mode 100644 index 0000000000000000000000000000000000000000..6e6801ab0e10a9fb08bf328fb010a4fa3e279d73 GIT binary patch literal 1569 zcmZ`(TT|0O7(Lq-Qqw5NP4J2rupkgG;H`*Ouv!h*GK}Rdl(j5Vl1wfP{w#fzbbp5iXl`Y)|;Ywis?El8s9Uap?4BKRfLWPj|wf zkJz^bSc`-xED+GhMqv5kfNu#;kUB-nvVBwXAg)&p+pX*S0m)CTBYfJr=?J~8RK*V5 z8ZQZ{{=gX}XXG|D3}T4kMuPZ}fFA>f^QROeRxbBKaPQ=4&G<*YgnX@FQNt46Btx&o zQpxg?g0~vpq0DeAfyoK-3|A70mhD5X;JthO1anu&QAV>l!v>xPoL0UF1fTIeLtLJK!#kM`|+95sg38)_-~?#yf7-?s zGAb{ejupej3lrN!v9o!Lp2ywT;5jpVDVYtAES$-2%VikZN{temZon~$e!AD>FGYVc zG#D4^V9(Rc#_|w2-Ox zbv4nwd~fO)%1R5_YOkU+aqf9$I(-cFCvqd17PRVDoNwa7F?znC_iW~3JJTl#r6CDj zheGW|x_bxEM+AoHxkL08h}K6UCW+2QWMZOOtm7KZqdOIEaf1{{(VQY~;uc}v!5nT= bo52{(lv|8)(h0O(5~i+m!-iwsPfWbXb@Ewo`9XGj4kgr&)7+ zrSCmuBHUMjz@mK|SuNkA;m~S1;r=`2?kacBdhG=&RGzyngRsoxt~?F}Mp`|!z}&D% zMoqqn+)y3LnhF#vR9x2!9i5exr)|&QvkoFsplqp7`j*pDRk;J#BzUfT`mrwpVoP9tP-{>9*xSY8a4%hRxo9^$ zU!D%R(kWCfo!4%0E|OXE{~t;v2&CT|oauBf)%TIpED3sB&#`z2z%5 z`R?@>3*z{J#WhNP2GBo z>Z6{4K{OfuCJH3EMx-x^w2mA;5Wi-V?;`H8$soX0OpxIks$@1nX4mMY`A>2exK0_v F)E|nf2-yGt literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontierTest.class b/SearchFramework1.0.1/out/test/SearchFramework1.0.1/xu/solver/heuristic/LinkedFrontierTest.class new file mode 100644 index 0000000000000000000000000000000000000000..f598b290b957d4e70be4d1716401e3e22ca6b571 GIT binary patch literal 2537 zcmb7G+fy4=9R5y7c9V2zQwp@{jf%7eD5NcIZK0*D6a)=W8w!HgC0XD=vb%0JwA4$z zzd6qM;EcXFM;wubDv?f3m|=R1eo z{^!66^_ z^K@VfI`9-XPlu4eU>HLf=H?R9pJB*l1}Awm!Y{7yXq1~VZk}b_xQYoC&j~1Jq$%BQ zfvQ;ZsDQu6N*e;(64Eq=^4Uql8PO**v{I9>QhH`ocO=hCi+*=T<^*DiYx#K2%FG*1 ze8$K-GUv)voJ`Ca=|0CYT}ft)oZBT3u%@OAhkBFz9A&d9%Q4F2AzCC*aH>QSXnF|K z%&@JTbfskq)D|t;jzw{1<4IR{*`{Laj$yi#A$u06rWdKXLEZLJQSrQr7X+f0^Av5? z7?n9m^b4kG5ufZ*mU|PHGaaAJQ@N#YX{Mz)9lumco?&T$$h{@ybqZ?FCiFpT z-cT{6VHz_Gl^SB0)iB4?3^!Sr8Z6ivUV)<`r@=*D#k_{AxW-MRh6P;L@G4%@@H$i8 zU<+4qL&KXqdW*?#;~fp}asduKxBy&M%7v>I&*+rp@Z_wKqNN%yy>cDA{iQ_@mv?0* zK0q6zyB3M8X?-EqgxNc+dC)NV& zv9csa4v~ySV;jHW!x)GS3~+zGqM3NqI7UVNj+^YK6`U;h|kbJ2#dTz+L zM*B_|6mk8gH>oY-*GYrW>*SJL$hk(AXjY!cb;T-6D}Kq5rkivfL(dXnhqo=2%jDE% zP=;<3O5t7wc5!OKX@iW=)gr*5-!DlHoiLm;U631YV2M_`IKApnUB<|GitbEZ@}=XC zO|ZL2TIN!^lOA?18+JxdkxfKp5M~Wa#26$5Cm}pLX=C^slFZ9{%{~p-Tt? zkJ2bky`VnOvIOy!_qvH%#apb#K^kjC01n|Xnt|?yMlwQV-(9Hm2l4ANeB+C#`WpTv z1QN?o##MC*>fkbhI>LOWRJ5^;JYaBNPQ{tGAUZX?loV*4P0?;lt_3j zhdpEeD+dDa{S?*I?JHpa&6Ph`3{_w;eB`y;u@yDgg&ib>Ivhbg`mqzkh++b}k;5Kb z$6maTefSLf@dfE^krek6Y3*kc%N??Dm*n&(u~!fiThJ_;&?-96CeEQ^ z5v@2(0^UUy+R#qIJtV#))wfV?{o(`4qXm8(r7WAFtl&2&DjHPyR2)+g^u8UyUpVkL ZK3CB}gFu9S%oR__3F-w-QtQLx{{p^te(C@K literal 0 HcmV?d00001 diff --git a/SearchFramework1.0.1/resources/pathfinding.txt b/SearchFramework1.0.1/resources/pathfinding.txt new file mode 100644 index 0000000..802047f --- /dev/null +++ b/SearchFramework1.0.1/resources/pathfinding.txt @@ -0,0 +1,4 @@ +3 5 0 8 4 2 1 7 3 6 1 2 3 4 5 6 7 8 0 +3 6 4 7 8 5 0 3 2 1 1 2 3 4 5 6 7 8 0 +3 8 6 7 2 5 4 3 0 1 1 2 3 4 5 6 7 8 0 +4 8 13 0 6 1 15 9 14 3 4 5 11 7 2 10 12 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 \ No newline at end of file diff --git a/SearchFramework1.0.1/src/META-INF/MANIFEST.MF b/SearchFramework1.0.1/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..8b6e977 --- /dev/null +++ b/SearchFramework1.0.1/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: runner.SearchRunner + diff --git a/SearchFramework1.0.1/src/algs4/util/In.java b/SearchFramework1.0.1/src/algs4/util/In.java new file mode 100644 index 0000000..3d1c060 --- /dev/null +++ b/SearchFramework1.0.1/src/algs4/util/In.java @@ -0,0 +1,819 @@ +package algs4.util; + +/****************************************************************************** + * Compilation: javac In.java + * Execution: java In (basic test --- see source for required files) + * Dependencies: none + * + * Reads in data of various types from standard input, files, and URLs. + * + ******************************************************************************/ + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.net.Socket; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.InputMismatchException; +import java.util.Locale; +import java.util.NoSuchElementException; +import java.util.Scanner; +import java.util.regex.Pattern; + +/** + * Input. This class provides methods for reading strings + * and numbers from standard input, file input, URLs, and sockets. + *

+ * The Locale used is: language = English, country = US. This is consistent + * with the formatting conventions with Java floating-point literals, + * command-line arguments (via {@link Double#parseDouble(String)}) + * and standard output. + *

+ * For additional documentation, see + * Section 3.1 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + *

+ * Like {@link Scanner}, reading a token also consumes preceding Java + * whitespace, reading a full line consumes + * the following end-of-line delimeter, while reading a character consumes + * nothing extra. + *

+ * Whitespace is defined in {@link Character#isWhitespace(char)}. Newlines + * consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085; + * see + * Scanner.java (NB: Java 6u23 and earlier uses only \r, \r, \r\n). + * + * @author David Pritchard + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public final class In { + + ///// begin: section (1 of 2) of code duplicated from In to StdIn. + + // assume Unicode UTF-8 encoding + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with System.out. + private static final Locale LOCALE = Locale.US; + + // the default token separator; we maintain the invariant that this value + // is held by the scanner's delimiter between calls + private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+"); + + // makes whitespace characters significant + private static final Pattern EMPTY_PATTERN = Pattern.compile(""); + + // used to read the entire input. source: + // http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html + private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A"); + + //// end: section (1 of 2) of code duplicated from In to StdIn. + + private Scanner scanner; + + /** + * Initializes an input stream from standard input. + */ + public In() { + scanner = new Scanner(new BufferedInputStream(System.in), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + + /** + * Initializes an input stream from a socket. + * + * @param socket the socket + * @throws IllegalArgumentException if cannot open {@code socket} + * @throws IllegalArgumentException if {@code socket} is {@code null} + */ + public In(Socket socket) { + if (socket == null) throw new IllegalArgumentException("socket argument is null"); + try { + InputStream is = socket.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + socket, ioe); + } + } + + /** + * Initializes an input stream from a URL. + * + * @param url the URL + * @throws IllegalArgumentException if cannot open {@code url} + * @throws IllegalArgumentException if {@code url} is {@code null} + */ + public In(URL url) { + if (url == null) throw new IllegalArgumentException("url argument is null"); + try { + URLConnection site = url.openConnection(); + InputStream is = site.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + url, ioe); + } + } + + /** + * Initializes an input stream from a file. + * + * @param file the file + * @throws IllegalArgumentException if cannot open {@code file} + * @throws IllegalArgumentException if {@code file} is {@code null} + */ + public In(File file) { + if (file == null) throw new IllegalArgumentException("file argument is null"); + try { + // for consistency with StdIn, wrap with BufferedInputStream instead of use + // file as argument to Scanner + FileInputStream fis = new FileInputStream(file); + scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + file, ioe); + } + } + + + /** + * Initializes an input stream from a filename or web page name. + * + * @param name the filename or web page name + * @throws IllegalArgumentException if cannot open {@code name} as + * a file or URL + * @throws IllegalArgumentException if {@code name} is {@code null} + */ + public In(String name) { + if (name == null) throw new IllegalArgumentException("argument is null"); + if (name.length() == 0) throw new IllegalArgumentException("argument is the empty string"); + try { + // first try to read file from local file system + File file = new File(name); + if (file.exists()) { + // for consistency with StdIn, wrap with BufferedInputStream instead of use + // file as argument to Scanner + FileInputStream fis = new FileInputStream(file); + scanner = new Scanner(new BufferedInputStream(fis), CHARSET_NAME); + scanner.useLocale(LOCALE); + return; + } + + // resource relative to .class file + URL url = getClass().getResource(name); + + // resource relative to classloader root + if (url == null) { + url = getClass().getClassLoader().getResource(name); + } + + // or URL from web + if (url == null) { + url = new URL(name); + } + + URLConnection site = url.openConnection(); + + // in order to set User-Agent, replace above line with these two + // HttpURLConnection site = (HttpURLConnection) url.openConnection(); + // site.addRequestProperty("User-Agent", "Mozilla/4.76"); + + InputStream is = site.getInputStream(); + scanner = new Scanner(new BufferedInputStream(is), CHARSET_NAME); + scanner.useLocale(LOCALE); + } + catch (IOException ioe) { + throw new IllegalArgumentException("Could not open " + name, ioe); + } + } + + /** + * Initializes an input stream from a given {@link Scanner} source; use with + * {@code new Scanner(String)} to read from a string. + *

+ * Note that this does not create a defensive copy, so the + * scanner will be mutated as you read on. + * + * @param scanner the scanner + * @throws IllegalArgumentException if {@code scanner} is {@code null} + */ + public In(Scanner scanner) { + if (scanner == null) throw new IllegalArgumentException("scanner argument is null"); + this.scanner = scanner; + } + + /** + * Returns true if this input stream exists. + * + * @return {@code true} if this input stream exists; {@code false} otherwise + */ + public boolean exists() { + return scanner != null; + } + + //// begin: section (2 of 2) of code duplicated from In to StdIn, + //// with all methods changed from "public" to "public static". + + /** + * Returns true if input stream is empty (except possibly whitespace). + * Use this to know whether the next call to {@link #readString()}, + * {@link #readDouble()}, etc will succeed. + * + * @return {@code true} if this input stream is empty (except possibly whitespace); + * {@code false} otherwise + */ + public boolean isEmpty() { + return !scanner.hasNext(); + } + + /** + * Returns true if this input stream has a next line. + * Use this method to know whether the + * next call to {@link #readLine()} will succeed. + * This method is functionally equivalent to {@link #hasNextChar()}. + * + * @return {@code true} if this input stream has more input (including whitespace); + * {@code false} otherwise + */ + public boolean hasNextLine() { + return scanner.hasNextLine(); + } + + /** + * Returns true if this input stream has more input (including whitespace). + * Use this method to know whether the next call to {@link #readChar()} will succeed. + * This method is functionally equivalent to {@link #hasNextLine()}. + * + * @return {@code true} if this input stream has more input (including whitespace); + * {@code false} otherwise + */ + public boolean hasNextChar() { + scanner.useDelimiter(EMPTY_PATTERN); + boolean result = scanner.hasNext(); + scanner.useDelimiter(WHITESPACE_PATTERN); + return result; + } + + + /** + * Reads and returns the next line in this input stream. + * + * @return the next line in this input stream; {@code null} if no such line + */ + public String readLine() { + String line; + try { + line = scanner.nextLine(); + } + catch (NoSuchElementException e) { + line = null; + } + return line; + } + + /** + * Reads and returns the next character in this input stream. + * + * @return the next {@code char} in this input stream + * @throws NoSuchElementException if the input stream is empty + */ + public char readChar() { + scanner.useDelimiter(EMPTY_PATTERN); + try { + String ch = scanner.next(); + assert ch.length() == 1 : "Internal (Std)In.readChar() error!" + + " Please contact the authors."; + scanner.useDelimiter(WHITESPACE_PATTERN); + return ch.charAt(0); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'char' value from the input stream, " + + "but no more tokens are available"); + } + } + + + /** + * Reads and returns the remainder of this input stream, as a string. + * + * @return the remainder of this input stream, as a string + */ + public String readAll() { + if (!scanner.hasNextLine()) + return ""; + + String result = scanner.useDelimiter(EVERYTHING_PATTERN).next(); + // not that important to reset delimeter, since now scanner is empty + scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway + return result; + } + + + /** + * Reads the next token from this input stream and returns it as a {@code String}. + * + * @return the next {@code String} in this input stream + * @throws NoSuchElementException if the input stream is empty + */ + public String readString() { + try { + return scanner.next(); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'String' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code int}, + * and returns the {@code int}. + * + * @return the next {@code int} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as an {@code int} + */ + public int readInt() { + try { + return scanner.nextInt(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read an 'int' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read an 'int' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code double}, + * and returns the {@code double}. + * + * @return the next {@code double} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code double} + */ + public double readDouble() { + try { + return scanner.nextDouble(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'double' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'double' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code float}, + * and returns the {@code float}. + * + * @return the next {@code float} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code float} + */ + public float readFloat() { + try { + return scanner.nextFloat(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'float' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'float' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code long}, + * and returns the {@code long}. + * + * @return the next {@code long} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code long} + */ + public long readLong() { + try { + return scanner.nextLong(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'long' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'long' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code short}, + * and returns the {@code short}. + * + * @return the next {@code short} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code short} + */ + public short readShort() { + try { + return scanner.nextShort(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'short' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'short' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code byte}, + * and returns the {@code byte}. + *

+ * To read binary data, use {@link BinaryIn}. + * + * @return the next {@code byte} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code byte} + */ + public byte readByte() { + try { + return scanner.nextByte(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'byte' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read a 'byte' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from this input stream, parses it as a {@code boolean} + * (interpreting either {@code "true"} or {@code "1"} as {@code true}, + * and either {@code "false"} or {@code "0"} as {@code false}). + * + * @return the next {@code boolean} in this input stream + * @throws NoSuchElementException if the input stream is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code boolean} + */ + public boolean readBoolean() { + try { + String token = readString(); + if ("true".equalsIgnoreCase(token)) return true; + if ("false".equalsIgnoreCase(token)) return false; + if ("1".equals(token)) return true; + if ("0".equals(token)) return false; + throw new InputMismatchException("attempts to read a 'boolean' value from the input stream, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'boolean' value from the input stream, " + + "but no more tokens are available"); + } + } + + /** + * Reads all remaining tokens from this input stream and returns them as + * an array of strings. + * + * @return all remaining tokens in this input stream, as an array of strings + */ + public String[] readAllStrings() { + // we could use readAll.trim().split(), but that's not consistent + // since trim() uses characters 0x00..0x20 as whitespace + String[] tokens = WHITESPACE_PATTERN.split(readAll()); + if (tokens.length == 0 || tokens[0].length() > 0) + return tokens; + String[] decapitokens = new String[tokens.length-1]; + for (int i = 0; i < tokens.length-1; i++) + decapitokens[i] = tokens[i+1]; + return decapitokens; + } + + /** + * Reads all remaining lines from this input stream and returns them as + * an array of strings. + * + * @return all remaining lines in this input stream, as an array of strings + */ + public String[] readAllLines() { + ArrayList lines = new ArrayList(); + while (hasNextLine()) { + lines.add(readLine()); + } + return lines.toArray(new String[lines.size()]); + } + + + /** + * Reads all remaining tokens from this input stream, parses them as integers, + * and returns them as an array of integers. + * + * @return all remaining lines in this input stream, as an array of integers + */ + public int[] readAllInts() { + String[] fields = readAllStrings(); + int[] vals = new int[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Integer.parseInt(fields[i]); + return vals; + } + + /** + * Reads all remaining tokens from this input stream, parses them as longs, + * and returns them as an array of longs. + * + * @return all remaining lines in this input stream, as an array of longs + */ + public long[] readAllLongs() { + String[] fields = readAllStrings(); + long[] vals = new long[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Long.parseLong(fields[i]); + return vals; + } + + /** + * Reads all remaining tokens from this input stream, parses them as doubles, + * and returns them as an array of doubles. + * + * @return all remaining lines in this input stream, as an array of doubles + */ + public double[] readAllDoubles() { + String[] fields = readAllStrings(); + double[] vals = new double[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Double.parseDouble(fields[i]); + return vals; + } + + ///// end: section (2 of 2) of code duplicated from In to StdIn */ + + /** + * Closes this input stream. + */ + public void close() { + scanner.close(); + } + + /** + * Reads all integers from a file and returns them as + * an array of integers. + * + * @param filename the name of the file + * @return the integers in the file + * @deprecated Replaced by {@code new In(filename)}.{@link #readAllInts()}. + */ + @Deprecated + public static int[] readInts(String filename) { + return new In(filename).readAllInts(); + } + + /** + * Reads all doubles from a file and returns them as + * an array of doubles. + * + * @param filename the name of the file + * @return the doubles in the file + * @deprecated Replaced by {@code new In(filename)}.{@link #readAllDoubles()}. + */ + @Deprecated + public static double[] readDoubles(String filename) { + return new In(filename).readAllDoubles(); + } + + /** + * Reads all strings from a file and returns them as + * an array of strings. + * + * @param filename the name of the file + * @return the strings in the file + * @deprecated Replaced by {@code new In(filename)}.{@link #readAllStrings()}. + */ + @Deprecated + public static String[] readStrings(String filename) { + return new In(filename).readAllStrings(); + } + + /** + * Reads all integers from standard input and returns them + * an array of integers. + * + * @return the integers on standard input + * @deprecated Replaced by {@link StdIn#readAllInts()}. + */ + @Deprecated + public static int[] readInts() { + return new In().readAllInts(); + } + + /** + * Reads all doubles from standard input and returns them as + * an array of doubles. + * + * @return the doubles on standard input + * @deprecated Replaced by {@link StdIn#readAllDoubles()}. + */ + @Deprecated + public static double[] readDoubles() { + return new In().readAllDoubles(); + } + + /** + * Reads all strings from standard input and returns them as + * an array of strings. + * + * @return the strings on standard input + * @deprecated Replaced by {@link StdIn#readAllStrings()}. + */ + @Deprecated + public static String[] readStrings() { + return new In().readAllStrings(); + } + + /** + * Unit tests the {@code In} data type. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + In in; + String urlName = "https://introcs.cs.princeton.edu/java/stdlib/InTest.txt"; + + // read from a URL + System.out.println("readAll() from URL " + urlName); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In(urlName); + System.out.println(in.readAll()); + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + // read one line at a time from URL + System.out.println("readLine() from URL " + urlName); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In(urlName); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + // read one string at a time from URL + System.out.println("readString() from URL " + urlName); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In(urlName); + while (!in.isEmpty()) { + String s = in.readString(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + + // read one line at a time from file in current directory + System.out.println("readLine() from current directory"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("./InTest.txt"); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + + // read one line at a time from file using relative path + System.out.println("readLine() from relative path"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("../stdlib/InTest.txt"); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + // read one char at a time + System.out.println("readChar() from file"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("InTest.txt"); + while (!in.isEmpty()) { + char c = in.readChar(); + System.out.print(c); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + System.out.println(); + + // read one line at a time from absolute OS X / Linux path + System.out.println("readLine() from absolute OS X / Linux path"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("/n/fs/introcs/www/java/stdlib/InTest.txt"); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + + // read one line at a time from absolute Windows path + System.out.println("readLine() from absolute Windows path"); + System.out.println("---------------------------------------------------------------------------"); + try { + in = new In("G:\\www\\introcs\\stdlib\\InTest.txt"); + while (!in.isEmpty()) { + String s = in.readLine(); + System.out.println(s); + } + System.out.println(); + } + catch (IllegalArgumentException e) { + System.out.println(e); + } + System.out.println(); + + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/SearchFramework1.0.1/src/algs4/util/Out.java b/SearchFramework1.0.1/src/algs4/util/Out.java new file mode 100644 index 0000000..1ec583c --- /dev/null +++ b/SearchFramework1.0.1/src/algs4/util/Out.java @@ -0,0 +1,341 @@ +package algs4.util; +/****************************************************************************** + * Compilation: javac Out.java + * Execution: java Out + * Dependencies: none + * + * Writes data of various types to: stdout, file, or socket. + * + ******************************************************************************/ + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.Locale; + +/** + * This class provides methods for writing strings and numbers to + * various output streams, including standard output, file, and sockets. + *

+ * For additional documentation, see + * Section 3.1 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public class Out { + + // force Unicode UTF-8 encoding; otherwise it's system dependent + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with In + private static final Locale LOCALE = Locale.US; + + private PrintWriter out; + + /** + * Initializes an output stream from a {@link OutputStream}. + * + * @param os the {@code OutputStream} + */ + public Out(OutputStream os) { + try { + OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME); + out = new PrintWriter(osw, true); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Initializes an output stream from standard output. + */ + public Out() { + this(System.out); + } + + /** + * Initializes an output stream from a socket. + * + * @param socket the socket + */ + public Out(Socket socket) { + try { + OutputStream os = socket.getOutputStream(); + OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME); + out = new PrintWriter(osw, true); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Initializes an output stream from a file. + * + * @param filename the name of the file + */ + public Out(String filename) { + try { + OutputStream os = new FileOutputStream(filename); + OutputStreamWriter osw = new OutputStreamWriter(os, CHARSET_NAME); + out = new PrintWriter(osw, true); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Closes the output stream. + */ + public void close() { + out.close(); + } + + /** + * Terminates the current line by printing the line-separator string. + */ + public void println() { + out.println(); + } + + /** + * Prints an object to this output stream and then terminates the line. + * + * @param x the object to print + */ + public void println(Object x) { + out.println(x); + } + + /** + * Prints a boolean to this output stream and then terminates the line. + * + * @param x the boolean to print + */ + public void println(boolean x) { + out.println(x); + } + + /** + * Prints a character to this output stream and then terminates the line. + * + * @param x the character to print + */ + public void println(char x) { + out.println(x); + } + + /** + * Prints a double to this output stream and then terminates the line. + * + * @param x the double to print + */ + public void println(double x) { + out.println(x); + } + + /** + * Prints a float to this output stream and then terminates the line. + * + * @param x the float to print + */ + public void println(float x) { + out.println(x); + } + + /** + * Prints an integer to this output stream and then terminates the line. + * + * @param x the integer to print + */ + public void println(int x) { + out.println(x); + } + + /** + * Prints a long to this output stream and then terminates the line. + * + * @param x the long to print + */ + public void println(long x) { + out.println(x); + } + + /** + * Prints a byte to this output stream and then terminates the line. + *

+ * To write binary data, see {@link BinaryOut}. + * + * @param x the byte to print + */ + public void println(byte x) { + out.println(x); + } + + + + /** + * Flushes this output stream. + */ + public void print() { + out.flush(); + } + + /** + * Prints an object to this output stream and flushes this output stream. + * + * @param x the object to print + */ + public void print(Object x) { + out.print(x); + out.flush(); + } + + /** + * Prints a boolean to this output stream and flushes this output stream. + * + * @param x the boolean to print + */ + public void print(boolean x) { + out.print(x); + out.flush(); + } + + /** + * Prints a character to this output stream and flushes this output stream. + * + * @param x the character to print + */ + public void print(char x) { + out.print(x); + out.flush(); + } + + /** + * Prints a double to this output stream and flushes this output stream. + * + * @param x the double to print + */ + public void print(double x) { + out.print(x); + out.flush(); + } + + /** + * Prints a float to this output stream and flushes this output stream. + * + * @param x the float to print + */ + public void print(float x) { + out.print(x); + out.flush(); + } + + /** + * Prints an integer to this output stream and flushes this output stream. + * + * @param x the integer to print + */ + public void print(int x) { + out.print(x); + out.flush(); + } + + /** + * Prints a long integer to this output stream and flushes this output stream. + * + * @param x the long integer to print + */ + public void print(long x) { + out.print(x); + out.flush(); + } + + /** + * Prints a byte to this output stream and flushes this output stream. + * + * @param x the byte to print + */ + public void print(byte x) { + out.print(x); + out.flush(); + } + + /** + * Prints a formatted string to this output stream, using the specified format + * string and arguments, and then flushes this output stream. + * + * @param format the format string + * @param args the arguments accompanying the format string + */ + public void printf(String format, Object... args) { + out.printf(LOCALE, format, args); + out.flush(); + } + + /** + * Prints a formatted string to this output stream, using the specified + * locale, format string, and arguments, and then flushes this output stream. + * + * @param locale the locale + * @param format the format string + * @param args the arguments accompanying the format string + */ + public void printf(Locale locale, String format, Object... args) { + out.printf(locale, format, args); + out.flush(); + } + + + /** + * A test client. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + Out out; + + // write to stdout + out = new Out(); + out.println("Test 1"); + out.close(); + + // write to a file + out = new Out("test.txt"); + out.println("Test 2"); + out.close(); + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/SearchFramework1.0.1/src/algs4/util/StdIn.java b/SearchFramework1.0.1/src/algs4/util/StdIn.java new file mode 100644 index 0000000..1123102 --- /dev/null +++ b/SearchFramework1.0.1/src/algs4/util/StdIn.java @@ -0,0 +1,696 @@ +/****************************************************************************** + * Compilation: javac StdIn.java + * Execution: java StdIn (interactive test of basic functionality) + * Dependencies: none + * + * Reads in data of various types from standard input. + * + ******************************************************************************/ + +package algs4.util; + +import java.util.ArrayList; +import java.util.InputMismatchException; +import java.util.Locale; +import java.util.NoSuchElementException; +import java.util.Scanner; +import java.util.regex.Pattern; + +/** + * The {@code StdIn} class provides static methods for reading strings + * and numbers from standard input. + * These functions fall into one of four categories: + *

    + *
  • those for reading individual tokens from standard input, one at a time, + * and converting each to a number, string, or boolean + *
  • those for reading characters from standard input, one at a time + *
  • those for reading lines from standard input, one at a time + *
  • those for reading a sequence of values of the same type from standard input, + * and returning the values in an array + *
+ *

+ * Generally, it is best not to mix functions from the different + * categories in the same program. + *

+ * Getting started. + * To use this class, you must have {@code StdIn.class} in your + * Java classpath. If you used our autoinstaller, you should be all set. + * Otherwise, either download + * stdlib.jar + * and add to your Java classpath or download + * StdIn.java + * and put a copy in your working directory. + *

+ * Reading tokens from standard input and converting to numbers and strings. + * You can use the following methods to read numbers, strings, and booleans + * from standard input one at a time: + *

    + *
  • {@link #isEmpty()} + *
  • {@link #readInt()} + *
  • {@link #readDouble()} + *
  • {@link #readString()} + *
  • {@link #readShort()} + *
  • {@link #readLong()} + *
  • {@link #readFloat()} + *
  • {@link #readByte()} + *
  • {@link #readBoolean()} + *
+ *

+ * The first method returns true if standard input has no more tokens. + * Each other method skips over any input that is whitespace. Then, it reads + * the next token and attempts to convert it into a value of the specified + * type. If it succeeds, it returns that value; otherwise, it + * throws an {@link InputMismatchException}. + *

+ * Whitespace includes spaces, tabs, and newlines; the full definition + * is inherited from {@link Character#isWhitespace(char)}. + * A token is a maximal sequence of non-whitespace characters. + * The precise rules for describing which tokens can be converted to + * integers and floating-point numbers are inherited from + * Scanner, + * using the locale {@link Locale#US}; the rules + * for floating-point numbers are slightly different + * from those in {@link Double#valueOf(String)}, + * but unlikely to be of concern to most programmers. + *

+ * As an example, the following code fragment reads integers from standard input, + * one at a time, and prints them one per line. + *

+ *  while (!StdIn.isEmpty()) {
+ *      double value = StdIn.readDouble();
+ *      StdOut.println(value);
+ *  }
+ *  
+ *

+ * Reading characters from standard input. + * You can use the following two methods to read characters from standard input one at a time: + *

    + *
  • {@link #hasNextChar()} + *
  • {@link #readChar()} + *
+ *

+ * The first method returns true if standard input has more input (including whitespace). + * The second method reads and returns the next character of input on standard + * input (possibly a whitespace character). + *

+ * As an example, the following code fragment reads characters from standard input, + * one character at a time, and prints it to standard output. + *

+ *  while (StdIn.hasNextChar()) {
+ *      char c = StdIn.readChar();
+ *      StdOut.print(c);
+ *  }
+ *  
+ *

+ * Reading lines from standard input. + * You can use the following two methods to read lines from standard input: + *

    + *
  • {@link #hasNextLine()} + *
  • {@link #readLine()} + *
+ *

+ * The first method returns true if standard input has more input (including whitespace). + * The second method reads and returns the remaining portion of + * the next line of input on standard input (possibly whitespace), + * discarding the trailing line separator. + *

+ * A line separator is defined to be one of the following strings: + * {@code \n} (Linux), {@code \r} (old Macintosh), + * {@code \r\n} (Windows), + * {@code \}{@code u2028}, {@code \}{@code u2029}, or {@code \}{@code u0085}. + *

+ * As an example, the following code fragment reads text from standard input, + * one line at a time, and prints it to standard output. + *

+ *  while (StdIn.hasNextLine()) {
+ *      String line = StdIn.readLine();
+ *      StdOut.println(line);
+ *  }
+ *  
+ *

+ * Reading a sequence of values of the same type from standard input. + * You can use the following methods to read a sequence numbers, strings, + * or booleans (all of the same type) from standard input: + *

    + *
  • {@link #readAllDoubles()} + *
  • {@link #readAllInts()} + *
  • {@link #readAllLongs()} + *
  • {@link #readAllStrings()} + *
  • {@link #readAllLines()} + *
  • {@link #readAll()} + *
+ *

+ * The first three methods read of all of remaining token on standard input + * and converts the tokens to values of + * the specified type, as in the corresponding + * {@code readDouble}, {@code readInt}, and {@code readString()} methods. + * The {@code readAllLines()} method reads all remaining lines on standard + * input and returns them as an array of strings. + * The {@code readAll()} method reads all remaining input on standard + * input and returns it as a string. + *

+ * As an example, the following code fragment reads all of the remaining + * tokens from standard input and returns them as an array of strings. + *

+ *  String[] words = StdIn.readAllStrings();
+ *  
+ *

+ * Differences with Scanner. + * {@code StdIn} and {@link Scanner} are both designed to parse + * tokens and convert them to primitive types and strings. + * The main differences are summarized below: + *

    + *
  • {@code StdIn} is a set of static methods and reads + * reads input from only standard input. It is suitable for use before + * a programmer knows about objects. + * See {@link In} for an object-oriented version that handles + * input from files, URLs, + * and sockets. + *
  • {@code StdIn} uses whitespace as the delimiter pattern + * that separates tokens. + * {@link Scanner} supports arbitrary delimiter patterns. + *
  • {@code StdIn} coerces the character-set encoding to UTF-8, + * which is the most widely used character encoding for Unicode. + *
  • {@code StdIn} coerces the locale to {@link Locale#US}, + * for consistency with {@link StdOut}, {@link Double#parseDouble(String)}, + * and floating-point literals. + *
  • {@code StdIn} has convenient methods for reading a single + * character; reading in sequences of integers, doubles, or strings; + * and reading in all of the remaining input. + *
+ *

+ * Historical note: {@code StdIn} preceded {@code Scanner}; when + * {@code Scanner} was introduced, this class was re-implemented to use {@code Scanner}. + *

+ * Using standard input. + * Standard input is a fundamental operating system abstraction on Mac OS X, + * Windows, and Linux. + * The methods in {@code StdIn} are blocking, which means that they + * will wait until you enter input on standard input. + * If your program has a loop that repeats until standard input is empty, + * you must signal that the input is finished. + * To do so, depending on your operating system and IDE, + * use either {@code } or {@code }, on its own line. + * If you are redirecting standard input from a file, you will not need + * to do anything to signal that the input is finished. + *

+ * Known bugs. + * Java's UTF-8 encoding does not recognize the optional + * byte-order mask. + * If the input begins with the optional byte-order mask, {@code StdIn} + * will have an extra character {@code \}{@code uFEFF} at the beginning. + *

+ * Reference. + * For additional documentation, + * see Section 1.5 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + * @author David Pritchard + */ +public final class StdIn { + + /*** begin: section (1 of 2) of code duplicated from In to StdIn. */ + + // assume Unicode UTF-8 encoding + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with System.out. + private static final Locale LOCALE = Locale.US; + + // the default token separator; we maintain the invariant that this value + // is held by the scanner's delimiter between calls + private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\p{javaWhitespace}+"); + + // makes whitespace significant + private static final Pattern EMPTY_PATTERN = Pattern.compile(""); + + // used to read the entire input + private static final Pattern EVERYTHING_PATTERN = Pattern.compile("\\A"); + + /*** end: section (1 of 2) of code duplicated from In to StdIn. */ + + private static Scanner scanner; + + // it doesn't make sense to instantiate this class + private StdIn() { } + + //// begin: section (2 of 2) of code duplicated from In to StdIn, + //// with all methods changed from "public" to "public static" + + /** + * Returns true if standard input is empty (except possibly for whitespace). + * Use this method to know whether the next call to {@link #readString()}, + * {@link #readDouble()}, etc will succeed. + * + * @return {@code true} if standard input is empty (except possibly + * for whitespace); {@code false} otherwise + */ + public static boolean isEmpty() { + return !scanner.hasNext(); + } + + /** + * Returns true if standard input has a next line. + * Use this method to know whether the + * next call to {@link #readLine()} will succeed. + * This method is functionally equivalent to {@link #hasNextChar()}. + * + * @return {@code true} if standard input has more input (including whitespace); + * {@code false} otherwise + */ + public static boolean hasNextLine() { + return scanner.hasNextLine(); + } + + /** + * Returns true if standard input has more input (including whitespace). + * Use this method to know whether the next call to {@link #readChar()} will succeed. + * This method is functionally equivalent to {@link #hasNextLine()}. + * + * @return {@code true} if standard input has more input (including whitespace); + * {@code false} otherwise + */ + public static boolean hasNextChar() { + scanner.useDelimiter(EMPTY_PATTERN); + boolean result = scanner.hasNext(); + scanner.useDelimiter(WHITESPACE_PATTERN); + return result; + } + + + /** + * Reads and returns the next line, excluding the line separator if present. + * + * @return the next line, excluding the line separator if present; + * {@code null} if no such line + */ + public static String readLine() { + String line; + try { + line = scanner.nextLine(); + } + catch (NoSuchElementException e) { + line = null; + } + return line; + } + + /** + * Reads and returns the next character. + * + * @return the next {@code char} + * @throws NoSuchElementException if standard input is empty + */ + public static char readChar() { + try { + scanner.useDelimiter(EMPTY_PATTERN); + String ch = scanner.next(); + assert ch.length() == 1 : "Internal (Std)In.readChar() error!" + + " Please contact the authors."; + scanner.useDelimiter(WHITESPACE_PATTERN); + return ch.charAt(0); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'char' value from standard input, " + + "but no more tokens are available"); + } + } + + + /** + * Reads and returns the remainder of the input, as a string. + * + * @return the remainder of the input, as a string + * @throws NoSuchElementException if standard input is empty + */ + public static String readAll() { + if (!scanner.hasNextLine()) + return ""; + + String result = scanner.useDelimiter(EVERYTHING_PATTERN).next(); + // not that important to reset delimeter, since now scanner is empty + scanner.useDelimiter(WHITESPACE_PATTERN); // but let's do it anyway + return result; + } + + + /** + * Reads the next token from standard input and returns it as a {@code String}. + * + * @return the next {@code String} + * @throws NoSuchElementException if standard input is empty + */ + public static String readString() { + try { + return scanner.next(); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'String' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as an integer, and returns the integer. + * + * @return the next integer on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as an {@code int} + */ + public static int readInt() { + try { + return scanner.nextInt(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read an 'int' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attemps to read an 'int' value from standard input, " + + "but no more tokens are available"); + } + + } + + /** + * Reads the next token from standard input, parses it as a double, and returns the double. + * + * @return the next double on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code double} + */ + public static double readDouble() { + try { + return scanner.nextDouble(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'double' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'double' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a float, and returns the float. + * + * @return the next float on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code float} + */ + public static float readFloat() { + try { + return scanner.nextFloat(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'float' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'float' value from standard input, " + + "but there no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a long integer, and returns the long integer. + * + * @return the next long integer on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code long} + */ + public static long readLong() { + try { + return scanner.nextLong(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'long' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'long' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a short integer, and returns the short integer. + * + * @return the next short integer on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code short} + */ + public static short readShort() { + try { + return scanner.nextShort(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'short' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'short' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a byte, and returns the byte. + * + * @return the next byte on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code byte} + */ + public static byte readByte() { + try { + return scanner.nextByte(); + } + catch (InputMismatchException e) { + String token = scanner.next(); + throw new InputMismatchException("attempts to read a 'byte' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'byte' value from standard input, " + + "but no more tokens are available"); + } + } + + /** + * Reads the next token from standard input, parses it as a boolean, + * and returns the boolean. + * + * @return the next boolean on standard input + * @throws NoSuchElementException if standard input is empty + * @throws InputMismatchException if the next token cannot be parsed as a {@code boolean}: + * {@code true} or {@code 1} for true, and {@code false} or {@code 0} for false, + * ignoring case + */ + public static boolean readBoolean() { + try { + String token = readString(); + if ("true".equalsIgnoreCase(token)) return true; + if ("false".equalsIgnoreCase(token)) return false; + if ("1".equals(token)) return true; + if ("0".equals(token)) return false; + throw new InputMismatchException("attempts to read a 'boolean' value from standard input, " + + "but the next token is \"" + token + "\""); + } + catch (NoSuchElementException e) { + throw new NoSuchElementException("attempts to read a 'boolean' value from standard input, " + + "but no more tokens are available"); + } + + } + + /** + * Reads all remaining tokens from standard input and returns them as an array of strings. + * + * @return all remaining tokens on standard input, as an array of strings + */ + public static String[] readAllStrings() { + // we could use readAll.trim().split(), but that's not consistent + // because trim() uses characters 0x00..0x20 as whitespace + String[] tokens = WHITESPACE_PATTERN.split(readAll()); + if (tokens.length == 0 || tokens[0].length() > 0) + return tokens; + + // don't include first token if it is leading whitespace + String[] decapitokens = new String[tokens.length-1]; + for (int i = 0; i < tokens.length - 1; i++) + decapitokens[i] = tokens[i+1]; + return decapitokens; + } + + /** + * Reads all remaining lines from standard input and returns them as an array of strings. + * @return all remaining lines on standard input, as an array of strings + */ + public static String[] readAllLines() { + ArrayList lines = new ArrayList(); + while (hasNextLine()) { + lines.add(readLine()); + } + return lines.toArray(new String[lines.size()]); + } + + /** + * Reads all remaining tokens from standard input, parses them as integers, and returns + * them as an array of integers. + * @return all remaining integers on standard input, as an array + * @throws InputMismatchException if any token cannot be parsed as an {@code int} + */ + public static int[] readAllInts() { + String[] fields = readAllStrings(); + int[] vals = new int[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Integer.parseInt(fields[i]); + return vals; + } + + /** + * Reads all remaining tokens from standard input, parses them as longs, and returns + * them as an array of longs. + * @return all remaining longs on standard input, as an array + * @throws InputMismatchException if any token cannot be parsed as a {@code long} + */ + public static long[] readAllLongs() { + String[] fields = readAllStrings(); + long[] vals = new long[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Long.parseLong(fields[i]); + return vals; + } + + /** + * Reads all remaining tokens from standard input, parses them as doubles, and returns + * them as an array of doubles. + * @return all remaining doubles on standard input, as an array + * @throws InputMismatchException if any token cannot be parsed as a {@code double} + */ + public static double[] readAllDoubles() { + String[] fields = readAllStrings(); + double[] vals = new double[fields.length]; + for (int i = 0; i < fields.length; i++) + vals[i] = Double.parseDouble(fields[i]); + return vals; + } + + //// end: section (2 of 2) of code duplicated from In to StdIn + + + // do this once when StdIn is initialized + static { + resync(); + } + + /** + * If StdIn changes, use this to reinitialize the scanner. + */ + private static void resync() { + setScanner(new Scanner(new java.io.BufferedInputStream(System.in), CHARSET_NAME)); + } + + private static void setScanner(Scanner scanner) { + StdIn.scanner = scanner; + StdIn.scanner.useLocale(LOCALE); + } + + /** + * Reads all remaining tokens, parses them as integers, and returns + * them as an array of integers. + * @return all remaining integers, as an array + * @throws InputMismatchException if any token cannot be parsed as an {@code int} + * @deprecated Replaced by {@link #readAllInts()}. + */ + @Deprecated + public static int[] readInts() { + return readAllInts(); + } + + /** + * Reads all remaining tokens, parses them as doubles, and returns + * them as an array of doubles. + * @return all remaining doubles, as an array + * @throws InputMismatchException if any token cannot be parsed as a {@code double} + * @deprecated Replaced by {@link #readAllDoubles()}. + */ + @Deprecated + public static double[] readDoubles() { + return readAllDoubles(); + } + + /** + * Reads all remaining tokens and returns them as an array of strings. + * @return all remaining tokens, as an array of strings + * @deprecated Replaced by {@link #readAllStrings()}. + */ + @Deprecated + public static String[] readStrings() { + return readAllStrings(); + } + + + /** + * Interactive test of basic functionality. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + + StdOut.print("Type a string: "); + String s = StdIn.readString(); + StdOut.println("Your string was: " + s); + StdOut.println(); + + StdOut.print("Type an int: "); + int a = StdIn.readInt(); + StdOut.println("Your int was: " + a); + StdOut.println(); + + StdOut.print("Type a boolean: "); + boolean b = StdIn.readBoolean(); + StdOut.println("Your boolean was: " + b); + StdOut.println(); + + StdOut.print("Type a double: "); + double c = StdIn.readDouble(); + StdOut.println("Your double was: " + c); + StdOut.println(); + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/SearchFramework1.0.1/src/algs4/util/StdOut.java b/SearchFramework1.0.1/src/algs4/util/StdOut.java new file mode 100644 index 0000000..04cd7dc --- /dev/null +++ b/SearchFramework1.0.1/src/algs4/util/StdOut.java @@ -0,0 +1,339 @@ +/****************************************************************************** + * Compilation: javac StdOut.java + * Execution: java StdOut + * Dependencies: none + * + * Writes data of various types to standard output. + * + ******************************************************************************/ + +package algs4.util; + +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.util.Locale; + +/** + * This class provides methods for printing strings and numbers to standard output. + *

+ * Getting started. + * To use this class, you must have {@code StdOut.class} in your + * Java classpath. If you used our autoinstaller, you should be all set. + * Otherwise, either download + * stdlib.jar + * and add to your Java classpath or download + * StdOut.java + * and put a copy in your working directory. + *

+ * Here is an example program that uses {@code StdOut}: + *

+ *   public class TestStdOut {
+ *       public static void main(String[] args) {
+ *           int a = 17;
+ *           int b = 23;
+ *           int sum = a + b;
+ *           StdOut.println("Hello, World");
+ *           StdOut.printf("%d + %d = %d\n", a, b, sum);
+ *       }
+ *   }
+ *  
+ *

+ * Differences with System.out. + * The behavior of {@code StdOut} is similar to that of {@link System#out}, + * but there are a few technical differences: + *

    + *
  • {@code StdOut} coerces the character-set encoding to UTF-8, + * which is a standard character encoding for Unicode. + *
  • {@code StdOut} coerces the locale to {@link Locale#US}, + * for consistency with {@link StdIn}, {@link Double#parseDouble(String)}, + * and floating-point literals. + *
  • {@code StdOut} flushes standard output after each call to + * {@code print()} so that text will appear immediately in the terminal. + *
+ *

+ * Reference. + * For additional documentation, + * see Section 1.5 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public final class StdOut { + + // force Unicode UTF-8 encoding; otherwise it's system dependent + private static final String CHARSET_NAME = "UTF-8"; + + // assume language = English, country = US for consistency with StdIn + private static final Locale LOCALE = Locale.US; + + // send output here + private static PrintWriter out; + + // this is called before invoking any methods + static { + try { + out = new PrintWriter(new OutputStreamWriter(System.out, CHARSET_NAME), true); + } + catch (UnsupportedEncodingException e) { + System.out.println(e); + } + } + + // don't instantiate + private StdOut() { } + + /** + * Terminates the current line by printing the line-separator string. + */ + public static void println() { + out.println(); + } + + /** + * Prints an object to this output stream and then terminates the line. + * + * @param x the object to print + */ + public static void println(Object x) { + out.println(x); + } + + /** + * Prints a boolean to standard output and then terminates the line. + * + * @param x the boolean to print + */ + public static void println(boolean x) { + out.println(x); + } + + /** + * Prints a character to standard output and then terminates the line. + * + * @param x the character to print + */ + public static void println(char x) { + out.println(x); + } + + /** + * Prints a double to standard output and then terminates the line. + * + * @param x the double to print + */ + public static void println(double x) { + out.println(x); + } + + /** + * Prints an integer to standard output and then terminates the line. + * + * @param x the integer to print + */ + public static void println(float x) { + out.println(x); + } + + /** + * Prints an integer to standard output and then terminates the line. + * + * @param x the integer to print + */ + public static void println(int x) { + out.println(x); + } + + /** + * Prints a long to standard output and then terminates the line. + * + * @param x the long to print + */ + public static void println(long x) { + out.println(x); + } + + /** + * Prints a short integer to standard output and then terminates the line. + * + * @param x the short to print + */ + public static void println(short x) { + out.println(x); + } + + /** + * Prints a byte to standard output and then terminates the line. + *

+ * To write binary data, see {@link BinaryStdOut}. + * + * @param x the byte to print + */ + public static void println(byte x) { + out.println(x); + } + + /** + * Flushes standard output. + */ + public static void print() { + out.flush(); + } + + /** + * Prints an object to standard output and flushes standard output. + * + * @param x the object to print + */ + public static void print(Object x) { + out.print(x); + out.flush(); + } + + /** + * Prints a boolean to standard output and flushes standard output. + * + * @param x the boolean to print + */ + public static void print(boolean x) { + out.print(x); + out.flush(); + } + + /** + * Prints a character to standard output and flushes standard output. + * + * @param x the character to print + */ + public static void print(char x) { + out.print(x); + out.flush(); + } + + /** + * Prints a double to standard output and flushes standard output. + * + * @param x the double to print + */ + public static void print(double x) { + out.print(x); + out.flush(); + } + + /** + * Prints a float to standard output and flushes standard output. + * + * @param x the float to print + */ + public static void print(float x) { + out.print(x); + out.flush(); + } + + /** + * Prints an integer to standard output and flushes standard output. + * + * @param x the integer to print + */ + public static void print(int x) { + out.print(x); + out.flush(); + } + + /** + * Prints a long integer to standard output and flushes standard output. + * + * @param x the long integer to print + */ + public static void print(long x) { + out.print(x); + out.flush(); + } + + /** + * Prints a short integer to standard output and flushes standard output. + * + * @param x the short integer to print + */ + public static void print(short x) { + out.print(x); + out.flush(); + } + + /** + * Prints a byte to standard output and flushes standard output. + * + * @param x the byte to print + */ + public static void print(byte x) { + out.print(x); + out.flush(); + } + + /** + * Prints a formatted string to standard output, using the specified format + * string and arguments, and then flushes standard output. + * + * + * @param format the format string + * @param args the arguments accompanying the format string + */ + public static void printf(String format, Object... args) { + out.printf(LOCALE, format, args); + out.flush(); + } + + /** + * Prints a formatted string to standard output, using the locale and + * the specified format string and arguments; then flushes standard output. + * + * @param locale the locale + * @param format the format string + * @param args the arguments accompanying the format string + */ + public static void printf(Locale locale, String format, Object... args) { + out.printf(locale, format, args); + out.flush(); + } + + /** + * Unit tests some of the methods in {@code StdOut}. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + + // write to stdout + StdOut.println("Test"); + StdOut.println(17); + StdOut.println(true); + StdOut.printf("%.6f\n", 1.0/7.0); + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/SearchFramework1.0.1/src/algs4/util/StdRandom.java b/SearchFramework1.0.1/src/algs4/util/StdRandom.java new file mode 100644 index 0000000..ac5c56c --- /dev/null +++ b/SearchFramework1.0.1/src/algs4/util/StdRandom.java @@ -0,0 +1,674 @@ +/****************************************************************************** + * Compilation: javac StdRandom.java + * Execution: java StdRandom + * Dependencies: StdOut.java + * + * A library of static methods to generate pseudo-random numbers from + * different distributions (bernoulli, uniform, gaussian, discrete, + * and exponential). Also includes a method for shuffling an array. + * + * + * % java StdRandom 5 + * seed = 1316600602069 + * 59 16.81826 true 8.83954 0 + * 32 91.32098 true 9.11026 0 + * 35 10.11874 true 8.95396 3 + * 92 32.88401 true 8.87089 0 + * 72 92.55791 true 9.46241 0 + * + * % java StdRandom 5 + * seed = 1316600616575 + * 96 60.17070 true 8.72821 0 + * 79 32.01607 true 8.58159 0 + * 81 59.49065 true 9.10423 1 + * 96 51.65818 true 9.02102 0 + * 99 17.55771 true 8.99762 0 + * + * % java StdRandom 5 1316600616575 + * seed = 1316600616575 + * 96 60.17070 true 8.72821 0 + * 79 32.01607 true 8.58159 0 + * 81 59.49065 true 9.10423 1 + * 96 51.65818 true 9.02102 0 + * 99 17.55771 true 8.99762 0 + * + * + * Remark + * ------ + * - Relies on randomness of nextDouble() method in java.util.Random + * to generate pseudo-random numbers in [0, 1). + * + * - This library allows you to set and get the pseudo-random number seed. + * + * - See http://www.honeylocust.com/RngPack/ for an industrial + * strength random number generator in Java. + * + ******************************************************************************/ + +package algs4.util; + +import java.util.Random; + +/** + * The {@code StdRandom} class provides static methods for generating + * random number from various discrete and continuous distributions, + * including uniform, Bernoulli, geometric, Gaussian, exponential, Pareto, + * Poisson, and Cauchy. It also provides method for shuffling an + * array or subarray and generating random permutations. + *

+ * By convention, all intervals are half open. For example, + * uniform(-1.0, 1.0) returns a random number between + * -1.0 (inclusive) and 1.0 (exclusive). + * Similarly, shuffle(a, lo, hi) shuffles the hi - lo + * elements in the array a[], starting at index lo + * (inclusive) and ending at index hi (exclusive). + *

+ * For additional documentation, + * see Section 2.2 of + * Computer Science: An Interdisciplinary Approach + * by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ +public final class StdRandom { + + private static Random random; // pseudo-random number generator + private static long seed; // pseudo-random number generator seed + + // static initializer + static { + // this is how the seed was set in Java 1.4 + seed = System.currentTimeMillis(); + random = new Random(seed); + } + + // don't instantiate + private StdRandom() { } + + /** + * Sets the seed of the pseudo-random number generator. + * This method enables you to produce the same sequence of "random" + * number for each execution of the program. + * Ordinarily, you should call this method at most once per program. + * + * @param s the seed + */ + public static void setSeed(long s) { + seed = s; + random = new Random(seed); + } + + /** + * Returns the seed of the pseudo-random number generator. + * + * @return the seed + */ + public static long getSeed() { + return seed; + } + + /** + * Returns a random real number uniformly in [0, 1). + * + * @return a random real number uniformly in [0, 1) + */ + public static double uniform() { + return random.nextDouble(); + } + + /** + * Returns a random integer uniformly in [0, n). + * + * @param n number of possible integers + * @return a random integer uniformly between 0 (inclusive) and {@code n} (exclusive) + * @throws IllegalArgumentException if {@code n <= 0} + */ + public static int uniform(int n) { + if (n <= 0) throw new IllegalArgumentException("argument must be positive: " + n); + return random.nextInt(n); + } + + + /** + * Returns a random long integer uniformly in [0, n). + * + * @param n number of possible {@code long} integers + * @return a random long integer uniformly between 0 (inclusive) and {@code n} (exclusive) + * @throws IllegalArgumentException if {@code n <= 0} + */ + public static long uniform(long n) { + if (n <= 0L) throw new IllegalArgumentException("argument must be positive: " + n); + + // https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long- + long r = random.nextLong(); + long m = n - 1; + + // power of two + if ((n & m) == 0L) { + return r & m; + } + + // reject over-represented candidates + long u = r >>> 1; + while (u + m - (r = u % n) < 0L) { + u = random.nextLong() >>> 1; + } + return r; + } + + /////////////////////////////////////////////////////////////////////////// + // STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA + // THE STATIC METHODS ABOVE. + /////////////////////////////////////////////////////////////////////////// + + /** + * Returns a random real number uniformly in [0, 1). + * + * @return a random real number uniformly in [0, 1) + * @deprecated Replaced by {@link #uniform()}. + */ + @Deprecated + public static double random() { + return uniform(); + } + + /** + * Returns a random integer uniformly in [a, b). + * + * @param a the left endpoint + * @param b the right endpoint + * @return a random integer uniformly in [a, b) + * @throws IllegalArgumentException if {@code b <= a} + * @throws IllegalArgumentException if {@code b - a >= Integer.MAX_VALUE} + */ + public static int uniform(int a, int b) { + if ((b <= a) || ((long) b - a >= Integer.MAX_VALUE)) { + throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")"); + } + return a + uniform(b - a); + } + + /** + * Returns a random real number uniformly in [a, b). + * + * @param a the left endpoint + * @param b the right endpoint + * @return a random real number uniformly in [a, b) + * @throws IllegalArgumentException unless {@code a < b} + */ + public static double uniform(double a, double b) { + if (!(a < b)) { + throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")"); + } + return a + uniform() * (b-a); + } + + /** + * Returns a random boolean from a Bernoulli distribution with success + * probability p. + * + * @param p the probability of returning {@code true} + * @return {@code true} with probability {@code p} and + * {@code false} with probability {@code 1 - p} + * @throws IllegalArgumentException unless {@code 0} ≤ {@code p} ≤ {@code 1.0} + */ + public static boolean bernoulli(double p) { + if (!(p >= 0.0 && p <= 1.0)) + throw new IllegalArgumentException("probability p must be between 0.0 and 1.0: " + p); + return uniform() < p; + } + + /** + * Returns a random boolean from a Bernoulli distribution with success + * probability 1/2. + * + * @return {@code true} with probability 1/2 and + * {@code false} with probability 1/2 + */ + public static boolean bernoulli() { + return bernoulli(0.5); + } + + /** + * Returns a random real number from a standard Gaussian distribution. + * + * @return a random real number from a standard Gaussian distribution + * (mean 0 and standard deviation 1). + */ + public static double gaussian() { + // use the polar form of the Box-Muller transform + double r, x, y; + do { + x = uniform(-1.0, 1.0); + y = uniform(-1.0, 1.0); + r = x*x + y*y; + } while (r >= 1 || r == 0); + return x * Math.sqrt(-2 * Math.log(r) / r); + + // Remark: y * Math.sqrt(-2 * Math.log(r) / r) + // is an independent random gaussian + } + + /** + * Returns a random real number from a Gaussian distribution with mean μ + * and standard deviation σ. + * + * @param mu the mean + * @param sigma the standard deviation + * @return a real number distributed according to the Gaussian distribution + * with mean {@code mu} and standard deviation {@code sigma} + */ + public static double gaussian(double mu, double sigma) { + return mu + sigma * gaussian(); + } + + /** + * Returns a random integer from a geometric distribution with success + * probability p. + * The integer represents the number of independent trials + * before the first success. + * + * @param p the parameter of the geometric distribution + * @return a random integer from a geometric distribution with success + * probability {@code p}; or {@code Integer.MAX_VALUE} if + * {@code p} is (nearly) equal to {@code 1.0}. + * @throws IllegalArgumentException unless {@code p >= 0.0} and {@code p <= 1.0} + */ + public static int geometric(double p) { + if (!(p >= 0)) { + throw new IllegalArgumentException("probability p must be greater than 0: " + p); + } + if (!(p <= 1.0)) { + throw new IllegalArgumentException("probability p must not be larger than 1: " + p); + } + // using algorithm given by Knuth + return (int) Math.ceil(Math.log(uniform()) / Math.log(1.0 - p)); + } + + /** + * Returns a random integer from a Poisson distribution with mean λ. + * + * @param lambda the mean of the Poisson distribution + * @return a random integer from a Poisson distribution with mean {@code lambda} + * @throws IllegalArgumentException unless {@code lambda > 0.0} and not infinite + */ + public static int poisson(double lambda) { + if (!(lambda > 0.0)) + throw new IllegalArgumentException("lambda must be positive: " + lambda); + if (Double.isInfinite(lambda)) + throw new IllegalArgumentException("lambda must not be infinite: " + lambda); + // using algorithm given by Knuth + // see http://en.wikipedia.org/wiki/Poisson_distribution + int k = 0; + double p = 1.0; + double expLambda = Math.exp(-lambda); + do { + k++; + p *= uniform(); + } while (p >= expLambda); + return k-1; + } + + /** + * Returns a random real number from the standard Pareto distribution. + * + * @return a random real number from the standard Pareto distribution + */ + public static double pareto() { + return pareto(1.0); + } + + /** + * Returns a random real number from a Pareto distribution with + * shape parameter α. + * + * @param alpha shape parameter + * @return a random real number from a Pareto distribution with shape + * parameter {@code alpha} + * @throws IllegalArgumentException unless {@code alpha > 0.0} + */ + public static double pareto(double alpha) { + if (!(alpha > 0.0)) + throw new IllegalArgumentException("alpha must be positive: " + alpha); + return Math.pow(1 - uniform(), -1.0/alpha) - 1.0; + } + + /** + * Returns a random real number from the Cauchy distribution. + * + * @return a random real number from the Cauchy distribution. + */ + public static double cauchy() { + return Math.tan(Math.PI * (uniform() - 0.5)); + } + + /** + * Returns a random integer from the specified discrete distribution. + * + * @param probabilities the probability of occurrence of each integer + * @return a random integer from a discrete distribution: + * {@code i} with probability {@code probabilities[i]} + * @throws IllegalArgumentException if {@code probabilities} is {@code null} + * @throws IllegalArgumentException if sum of array entries is not (very nearly) equal to {@code 1.0} + * @throws IllegalArgumentException unless {@code probabilities[i] >= 0.0} for each index {@code i} + */ + public static int discrete(double[] probabilities) { + if (probabilities == null) throw new IllegalArgumentException("argument array must not be null"); + double EPSILON = 1.0E-14; + double sum = 0.0; + for (int i = 0; i < probabilities.length; i++) { + if (!(probabilities[i] >= 0.0)) + throw new IllegalArgumentException("array entry " + i + " must be non-negative: " + probabilities[i]); + sum += probabilities[i]; + } + if (sum > 1.0 + EPSILON || sum < 1.0 - EPSILON) + throw new IllegalArgumentException("sum of array entries does not approximately equal 1.0: " + sum); + + // the for loop may not return a value when both r is (nearly) 1.0 and when the + // cumulative sum is less than 1.0 (as a result of floating-point roundoff error) + while (true) { + double r = uniform(); + sum = 0.0; + for (int i = 0; i < probabilities.length; i++) { + sum = sum + probabilities[i]; + if (sum > r) return i; + } + } + } + + /** + * Returns a random integer from the specified discrete distribution. + * + * @param frequencies the frequency of occurrence of each integer + * @return a random integer from a discrete distribution: + * {@code i} with probability proportional to {@code frequencies[i]} + * @throws IllegalArgumentException if {@code frequencies} is {@code null} + * @throws IllegalArgumentException if all array entries are {@code 0} + * @throws IllegalArgumentException if {@code frequencies[i]} is negative for any index {@code i} + * @throws IllegalArgumentException if sum of frequencies exceeds {@code Integer.MAX_VALUE} (231 - 1) + */ + public static int discrete(int[] frequencies) { + if (frequencies == null) throw new IllegalArgumentException("argument array must not be null"); + long sum = 0; + for (int i = 0; i < frequencies.length; i++) { + if (frequencies[i] < 0) + throw new IllegalArgumentException("array entry " + i + " must be non-negative: " + frequencies[i]); + sum += frequencies[i]; + } + if (sum == 0) + throw new IllegalArgumentException("at least one array entry must be positive"); + if (sum >= Integer.MAX_VALUE) + throw new IllegalArgumentException("sum of frequencies overflows an int"); + + // pick index i with probabilitity proportional to frequency + double r = uniform((int) sum); + sum = 0; + for (int i = 0; i < frequencies.length; i++) { + sum += frequencies[i]; + if (sum > r) return i; + } + + // can't reach here + assert false; + return -1; + } + + /** + * Returns a random real number from an exponential distribution + * with rate λ. + * + * @param lambda the rate of the exponential distribution + * @return a random real number from an exponential distribution with + * rate {@code lambda} + * @throws IllegalArgumentException unless {@code lambda > 0.0} + */ + public static double exp(double lambda) { + if (!(lambda > 0.0)) + throw new IllegalArgumentException("lambda must be positive: " + lambda); + return -Math.log(1 - uniform()) / lambda; + } + + /** + * Rearranges the elements of the specified array in uniformly random order. + * + * @param a the array to shuffle + * @throws IllegalArgumentException if {@code a} is {@code null} + */ + public static void shuffle(Object[] a) { + validateNotNull(a); + int n = a.length; + for (int i = 0; i < n; i++) { + int r = i + uniform(n-i); // between i and n-1 + Object temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified array in uniformly random order. + * + * @param a the array to shuffle + * @throws IllegalArgumentException if {@code a} is {@code null} + */ + public static void shuffle(double[] a) { + validateNotNull(a); + int n = a.length; + for (int i = 0; i < n; i++) { + int r = i + uniform(n-i); // between i and n-1 + double temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified array in uniformly random order. + * + * @param a the array to shuffle + * @throws IllegalArgumentException if {@code a} is {@code null} + */ + public static void shuffle(int[] a) { + validateNotNull(a); + int n = a.length; + for (int i = 0; i < n; i++) { + int r = i + uniform(n-i); // between i and n-1 + int temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified array in uniformly random order. + * + * @param a the array to shuffle + * @throws IllegalArgumentException if {@code a} is {@code null} + */ + public static void shuffle(char[] a) { + validateNotNull(a); + int n = a.length; + for (int i = 0; i < n; i++) { + int r = i + uniform(n-i); // between i and n-1 + char temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified subarray in uniformly random order. + * + * @param a the array to shuffle + * @param lo the left endpoint (inclusive) + * @param hi the right endpoint (exclusive) + * @throws IllegalArgumentException if {@code a} is {@code null} + * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)} + * + */ + public static void shuffle(Object[] a, int lo, int hi) { + validateNotNull(a); + validateSubarrayIndices(lo, hi, a.length); + + for (int i = lo; i < hi; i++) { + int r = i + uniform(hi-i); // between i and hi-1 + Object temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified subarray in uniformly random order. + * + * @param a the array to shuffle + * @param lo the left endpoint (inclusive) + * @param hi the right endpoint (exclusive) + * @throws IllegalArgumentException if {@code a} is {@code null} + * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)} + */ + public static void shuffle(double[] a, int lo, int hi) { + validateNotNull(a); + validateSubarrayIndices(lo, hi, a.length); + + for (int i = lo; i < hi; i++) { + int r = i + uniform(hi-i); // between i and hi-1 + double temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Rearranges the elements of the specified subarray in uniformly random order. + * + * @param a the array to shuffle + * @param lo the left endpoint (inclusive) + * @param hi the right endpoint (exclusive) + * @throws IllegalArgumentException if {@code a} is {@code null} + * @throws IllegalArgumentException unless {@code (0 <= lo) && (lo < hi) && (hi <= a.length)} + */ + public static void shuffle(int[] a, int lo, int hi) { + validateNotNull(a); + validateSubarrayIndices(lo, hi, a.length); + + for (int i = lo; i < hi; i++) { + int r = i + uniform(hi-i); // between i and hi-1 + int temp = a[i]; + a[i] = a[r]; + a[r] = temp; + } + } + + /** + * Returns a uniformly random permutation of n elements. + * + * @param n number of elements + * @throws IllegalArgumentException if {@code n} is negative + * @return an array of length {@code n} that is a uniformly random permutation + * of {@code 0}, {@code 1}, ..., {@code n-1} + */ + public static int[] permutation(int n) { + if (n < 0) throw new IllegalArgumentException("n must be non-negative: " + n); + int[] perm = new int[n]; + for (int i = 0; i < n; i++) + perm[i] = i; + shuffle(perm); + return perm; + } + + /** + * Returns a uniformly random permutation of k of n elements. + * + * @param n number of elements + * @param k number of elements to select + * @throws IllegalArgumentException if {@code n} is negative + * @throws IllegalArgumentException unless {@code 0 <= k <= n} + * @return an array of length {@code k} that is a uniformly random permutation + * of {@code k} of the elements from {@code 0}, {@code 1}, ..., {@code n-1} + */ + public static int[] permutation(int n, int k) { + if (n < 0) throw new IllegalArgumentException("n must be non-negative: " + n); + if (k < 0 || k > n) throw new IllegalArgumentException("k must be between 0 and n: " + k); + int[] perm = new int[k]; + for (int i = 0; i < k; i++) { + int r = uniform(i+1); // between 0 and i + perm[i] = perm[r]; + perm[r] = i; + } + for (int i = k; i < n; i++) { + int r = uniform(i+1); // between 0 and i + if (r < k) perm[r] = i; + } + return perm; + } + + // throw an IllegalArgumentException if x is null + // (x can be of type Object[], double[], int[], ...) + private static void validateNotNull(Object x) { + if (x == null) { + throw new IllegalArgumentException("argument must not be null"); + } + } + + // throw an exception unless 0 <= lo <= hi <= length + private static void validateSubarrayIndices(int lo, int hi, int length) { + if (lo < 0 || hi > length || lo > hi) { + throw new IllegalArgumentException("subarray indices out of bounds: [" + lo + ", " + hi + ")"); + } + } + + /** + * Unit tests the methods in this class. + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + int n = Integer.parseInt(args[0]); + if (args.length == 2) StdRandom.setSeed(Long.parseLong(args[1])); + double[] probabilities = { 0.5, 0.3, 0.1, 0.1 }; + int[] frequencies = { 5, 3, 1, 1 }; + String[] a = "A B C D E F G".split(" "); + + StdOut.println("seed = " + StdRandom.getSeed()); + for (int i = 0; i < n; i++) { + StdOut.printf("%2d ", uniform(100)); + StdOut.printf("%8.5f ", uniform(10.0, 99.0)); + StdOut.printf("%5b ", bernoulli(0.5)); + StdOut.printf("%7.5f ", gaussian(9.0, 0.2)); + StdOut.printf("%1d ", discrete(probabilities)); + StdOut.printf("%1d ", discrete(frequencies)); + StdOut.printf("%11d ", uniform(100000000000L)); + StdRandom.shuffle(a); + for (String s : a) + StdOut.print(s); + StdOut.println(); + } + } + +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/SearchFramework1.0.1/src/algs4/util/Stopwatch.java b/SearchFramework1.0.1/src/algs4/util/Stopwatch.java new file mode 100644 index 0000000..b8d228b --- /dev/null +++ b/SearchFramework1.0.1/src/algs4/util/Stopwatch.java @@ -0,0 +1,110 @@ +/****************************************************************************** + * Compilation: javac Stopwatch.java + * Execution: java Stopwatch n + * Dependencies: none + * + * A utility class to measure the running time (wall clock) of a program. + * + * % java8 Stopwatch 100000000 + * 6.666667e+11 0.5820 seconds + * 6.666667e+11 8.4530 seconds + * + ******************************************************************************/ + +package algs4.util; + +/** + * The {@code Stopwatch} data type is for measuring + * the time that elapses between the start and end of a + * programming task (wall-clock time). + * + * See {@link StopwatchCPU} for a version that measures CPU time. + * For additional documentation, + * see Section 1.4 of + * Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. + * + * @author Robert Sedgewick + * @author Kevin Wayne + */ + + +public class Stopwatch { + + private final long start; + + /** + * Initializes a new stopwatch. + */ + public Stopwatch() { + start = System.currentTimeMillis(); + } + + + /** + * Returns the elapsed CPU time (in seconds) since the stopwatch was created. + * + * @return elapsed CPU time (in seconds) since the stopwatch was created + */ + public double elapsedTime() { + long now = System.currentTimeMillis(); + return (now - start) / 1000.0; + } + + + /** + * Unit tests the {@code Stopwatch} data type. + * Takes a command-line argument {@code n} and computes the + * sum of the square roots of the first {@code n} positive integers, + * first using {@code Math.sqrt()}, then using {@code Math.pow()}. + * It prints to standard output the sum and the amount of time to + * compute the sum. Note that the discrete sum can be approximated by + * an integral - the sum should be approximately 2/3 * (n^(3/2) - 1). + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + int n = Integer.parseInt(args[0]); + + // sum of square roots of integers from 1 to n using Math.sqrt(x). + Stopwatch timer1 = new Stopwatch(); + double sum1 = 0.0; + for (int i = 1; i <= n; i++) { + sum1 += Math.sqrt(i); + } + double time1 = timer1.elapsedTime(); + StdOut.printf("%e (%.2f seconds)\n", sum1, time1); + + // sum of square roots of integers from 1 to n using Math.pow(x, 0.5). + Stopwatch timer2 = new Stopwatch(); + double sum2 = 0.0; + for (int i = 1; i <= n; i++) { + sum2 += Math.pow(i, 0.5); + } + double time2 = timer2.elapsedTime(); + StdOut.printf("%e (%.2f seconds)\n", sum2, time2); + } +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/SearchFramework1.0.1/src/algs4/util/StopwatchCPU.java b/SearchFramework1.0.1/src/algs4/util/StopwatchCPU.java new file mode 100644 index 0000000..4102749 --- /dev/null +++ b/SearchFramework1.0.1/src/algs4/util/StopwatchCPU.java @@ -0,0 +1,112 @@ +/****************************************************************************** + * Compilation: javac StopwatchCPU.java + * Execution: java StopwtachCPU n + * Dependencies: none + * + * A version of Stopwatch.java that measures CPU time on a single + * core or processor (instead of wall clock time). + * + * % java8 StopwatchCPU 100000000 + * 6.666667e+11 (1.05 seconds) + * 6.666667e+11 (7.50 seconds) + * + ******************************************************************************/ + +package algs4.util; + +import java.lang.management.ThreadMXBean; +import java.lang.management.ManagementFactory; + +/** + * The {@code StopwatchCPU} data type is for measuring + * the CPU time used during a programming task. + * + * See {@link Stopwatch} for a version that measures wall-clock time + * (the real time that elapses). + * + * @author Josh Hug + * @author Robert Sedgewick + * @author Kevin Wayne + */ + +public class StopwatchCPU { + private static final double NANOSECONDS_PER_SECOND = 1_000_000_000; + + private final ThreadMXBean threadTimer; + private final long start; + + /** + * Initializes a new stopwatch. + */ + public StopwatchCPU() { + threadTimer = ManagementFactory.getThreadMXBean(); + start = threadTimer.getCurrentThreadCpuTime(); + } + + /** + * Returns the elapsed CPU time (in seconds) since the stopwatch was created. + * + * @return elapsed CPU time (in seconds) since the stopwatch was created + */ + public double elapsedTime() { + long now = threadTimer.getCurrentThreadCpuTime(); + return (now - start) / NANOSECONDS_PER_SECOND; + } + + /** + * Unit tests the {@code StopwatchCPU} data type. + * Takes a command-line argument {@code n} and computes the + * sum of the square roots of the first {@code n} positive integers, + * first using {@code Math.sqrt()}, then using {@code Math.pow()}. + * It prints to standard output the sum and the amount of time to + * compute the sum. Note that the discrete sum can be approximated by + * an integral - the sum should be approximately 2/3 * (n^(3/2) - 1). + * + * @param args the command-line arguments + */ + public static void main(String[] args) { + int n = Integer.parseInt(args[0]); + + // sum of square roots of integers from 1 to n using Math.sqrt(x). + StopwatchCPU timer1 = new StopwatchCPU(); + double sum1 = 0.0; + for (int i = 1; i <= n; i++) { + sum1 += Math.sqrt(i); + } + double time1 = timer1.elapsedTime(); + StdOut.printf("%e (%.2f seconds)\n", sum1, time1); + + // sum of square roots of integers from 1 to n using Math.pow(x, 0.5). + StopwatchCPU timer2 = new StopwatchCPU(); + double sum2 = 0.0; + for (int i = 1; i <= n; i++) { + sum2 += Math.pow(i, 0.5); + } + double time2 = timer2.elapsedTime(); + StdOut.printf("%e (%.2f seconds)\n", sum2, time2); + } +} + +/****************************************************************************** + * Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. + * + * This file is part of algs4.jar, which accompanies the textbook + * + * Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, + * Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. + * http://algs4.cs.princeton.edu + * + * + * algs4.jar is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * algs4.jar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with algs4.jar. If not, see http://www.gnu.org/licenses. + ******************************************************************************/ diff --git a/SearchFramework1.0.1/src/core/problem/Action.java b/SearchFramework1.0.1/src/core/problem/Action.java new file mode 100644 index 0000000..757b6fe --- /dev/null +++ b/SearchFramework1.0.1/src/core/problem/Action.java @@ -0,0 +1,6 @@ +package core.problem; + +public abstract class Action { + public abstract void draw(); + public abstract int stepCost(); +} diff --git a/SearchFramework1.0.1/src/core/problem/Problem.java b/SearchFramework1.0.1/src/core/problem/Problem.java new file mode 100644 index 0000000..9499a33 --- /dev/null +++ b/SearchFramework1.0.1/src/core/problem/Problem.java @@ -0,0 +1,143 @@ +package core.problem; + +import core.solver.Node; +import core.solver.heuristic.Predictor; + +import java.util.ArrayList; +import java.util.Deque; + +/** + * 所有问题的抽象超类 + * initialState + * goal + */ +public abstract class Problem { + //成员变量 + protected State initialState; + protected State goal; + protected int size; //问题的规模:15-puzzle为4;寻路问题为Grid的边长;野人传教士为野人与传教士的人数 + + public Problem(State initialState, State goal) { + this.initialState = initialState; + this.goal = goal; + } + + public Problem(State initialState, State goal, int size) { + this(initialState, goal); + this.size = size; + } + + public State getInitialState() { + return initialState; + } + + public State getGoal() { + return goal; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public void setInitialState(State initialState) { + this.initialState = initialState; + } + + public void setGoal(State goal) { + this.goal = goal; + } + + /** + * 当前问题是否有解 + * @return 有解,true; 无解,false + * + */ + public abstract boolean solvable(); + + /** + * 从初始状态产生搜索树的根节点 + * @param predictor 启发函数 + * @return 当前问题的根结点 + */ + public final Node root(Predictor predictor) { + + return new Node(initialState, null, null, + 0, predictor.heuristics(initialState, goal)); + } + + /** + * 生成node的所有合法的后继结点 + * @param parent 父结点 + * @param predictor 启发函数 + * + * @return parent结点的所有子结点 + */ + public final Iterable childNodes(Node parent, Predictor predictor) { + ArrayList nodes = new ArrayList<>(); + //父结点的状态 + State parentState = parent.getState(); + //对于parentState上所有可能的action,但有的不可行 + for (Action action : parentState.actions()){ + //如果父结点状态下的动作是可行的 + if (applicable(parentState, action)){ + //得到后继状态 + State state = parentState.next(action); + //计算路径长度 = 父结点路径长度 + 进入后继状态所采取的动作的代价 + int pathCost = parent.getPathCost() + stepCost(state, action); + //使用predictor对state与goal的距离进行估值 + int heuristics = predictor.heuristics(state, goal); + //生成子结点 + Node child = new Node(state, parent, action, pathCost, heuristics); + nodes.add(child); + } + } + return nodes; + } + + /** + * + * @param state 当前状态 + * @param action 进入当前状态所采取的Action + * @return 进入当前状态的代价 + */ + public abstract int stepCost(State state, Action action); + + /** + * 在状态state上的action是否可用? + * @param state 当前状态 + * @param action 当前状态下所采用的动作 + * @return true:可用;false:不可用 + */ + protected abstract boolean applicable(State state, Action action); + + /** + * 判断某个状态state是否到达目标状态,多数情况下是判断跟目标状态是否相等。 + * + * @param state 要判断的状态 + * @return true:要判断的状态已经是目标状态;否则,false + */ + public boolean goal(State state){ + return state.equals(goal); + } + + /** + * 解路径的可视化 + * @param path 解路径 + */ + public abstract void showSolution(Deque path); + + /** + * 打印当前问题实例 + */ + public abstract void draw(); + + /** + * 打印解路径 + * @param path 解路径 + */ + public abstract void printPath(Deque path); +} diff --git a/SearchFramework1.0.1/src/core/problem/State.java b/SearchFramework1.0.1/src/core/problem/State.java new file mode 100644 index 0000000..b624a7b --- /dev/null +++ b/SearchFramework1.0.1/src/core/problem/State.java @@ -0,0 +1,24 @@ +package core.problem; + +import g04.problem.npuzzle.PuzzleState; + +/** + * + */ +public abstract class State { + + public abstract void draw(); // 在Console上,输出该状态 + + /** + * 当前状态采用action而进入的下一个状态 + * @param action 当前状态下,一个可行的action + * @return 后继状态 + */ + public abstract State next(Action action); + + /** + * 当前状态下所有可能的Action,但不一定都可行 + * @return 所有可能的Action的可迭代集合 + */ + public abstract Iterable actions(); +} \ No newline at end of file diff --git a/SearchFramework1.0.1/src/core/runner/EngineFeeder.java b/SearchFramework1.0.1/src/core/runner/EngineFeeder.java new file mode 100644 index 0000000..a7207b7 --- /dev/null +++ b/SearchFramework1.0.1/src/core/runner/EngineFeeder.java @@ -0,0 +1,85 @@ +package core.runner; + +import core.problem.Problem; +import core.problem.State; +import core.solver.Searcher; +import core.solver.heuristic.AbstractFrontier; +import core.solver.heuristic.BestFirstSearch; +import core.solver.heuristic.EvaluationType; +import core.solver.heuristic.Predictor; +import algs4.util.In; +import g04.problem.npuzzle.PuzzleState; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; + +/** + * 为搜索算法提供各样素材。包括 + * 问题problem, + * 使用的Frontier, + * 使用的估值函数 h函数,启发式函数 + * IDA Star搜索算法的一个实现 + * + */ +public abstract class EngineFeeder { + + /** + * 从文件输入流中读入NPuzzle问题的实例 + * @param io 输入流 + * @return 文件中所有NPuzzle实例 + */ + public abstract ArrayList getProblems(In io); + public abstract ArrayList getProblems(Scanner scanner); + /** + * 生成采取某种估值机制的Frontier + * @param type 结点评估器的类型 + * @return 使用该评估机制的一个Frontier实例 + */ + public abstract AbstractFrontier getFrontier(EvaluationType type); + + /** + * 获得对状态进行估值的Predictor + * @param type 估值函数的类型 + * @return 启发函数 + */ + public abstract Predictor getPredictor(HeuristicType type); + + /** + * 生成IdaStar搜索的一个实例,用来做对比实验 + */ + public abstract Searcher getIdaStar(); + + /** + * 用来提交头歌评分的Searcher + * @return 小组目前最佳的搜索引擎 + */ + public abstract Searcher getScoreSearcher(); + + /** + * 用来做对比实验的AStar, 对所有问题都是一样的 + * 使用不同的启发函数的AStar + */ + public Searcher getAStar(HeuristicType type){ + //获取Frontier,其Node以g(n)+h(n)的升序排列 + AbstractFrontier frontier = getFrontier(EvaluationType.FULL); + //以HashSet作为Explored表 + Set explored = new HashSet<>(); + //根据explored和frontier生成AStar引擎,并使用类型为type的启发函数 + return new BestFirstSearch(explored, frontier, PuzzleState.predictor(type)); + } + + /** + * 用来做对比实验的Dijkstra,对所有的问题都是一样的 + * @return Dijkstra搜索算法 + */ + public Searcher getDijkstra(){ + //获取Frontier,其Node以g(n)+h(n)的升序排列 + AbstractFrontier frontier = getFrontier(EvaluationType.PATH_COST); + //以HashSet作为Explored表 + Set explored = new HashSet<>(); + //根据explored和frontier生成AStar引擎,并使用曼哈顿距离作为启发函数 + return new BestFirstSearch(explored, frontier, (state, goal) -> 0); + } +} \ No newline at end of file diff --git a/SearchFramework1.0.1/src/core/runner/HeuristicType.java b/SearchFramework1.0.1/src/core/runner/HeuristicType.java new file mode 100644 index 0000000..40cd2e1 --- /dev/null +++ b/SearchFramework1.0.1/src/core/runner/HeuristicType.java @@ -0,0 +1,16 @@ +package core.runner; + +public enum HeuristicType { + //Npuzzle的启发函数 + MISPLACED, // 不在位将牌 + MANHATTAN, // 曼哈顿距离 + DISJOINT_PATTERN, + + //PathFinding的启发函数 (8方向的情况) + PF_EUCLID, // 欧几里得距离 + PF_MANHATTAN, // 8方向移动时,不是admissible的 + PF_GRID, // 尽可能走对角线,然后平行走,>= EUCLID + + //野人传教士问题 + MC_HARMONY //去掉野人会吃人的约束 +} diff --git a/SearchFramework1.0.1/src/core/runner/ProblemType.java b/SearchFramework1.0.1/src/core/runner/ProblemType.java new file mode 100644 index 0000000..3e07510 --- /dev/null +++ b/SearchFramework1.0.1/src/core/runner/ProblemType.java @@ -0,0 +1,8 @@ +package core.runner; + +public enum ProblemType { + NPUZZLE, // NPuzzle问题 + PATHFINDING, // 寻路问题 + SLIDING_BLOCKS, // 滑动积木块问题 + MISSIONARY_AND_CARNIVAL //野人传教士问题 +} diff --git a/SearchFramework1.0.1/src/core/runner/SearchRunner.java b/SearchFramework1.0.1/src/core/runner/SearchRunner.java new file mode 100644 index 0000000..6edcc75 --- /dev/null +++ b/SearchFramework1.0.1/src/core/runner/SearchRunner.java @@ -0,0 +1,74 @@ +package core.runner; + +import algs4.util.Stopwatch; +import core.problem.Problem; +import core.solver.Node; +import algs4.util.In; +import core.solver.heuristic.BestFirstSearch; +import g04.problem.npuzzle.MyFeeder; +import g04.solver.heuristic.IDAStarSearch; + +import java.util.ArrayList; +import java.util.Deque; + +public class SearchRunner { + + public static void main(String[] args) { + + //从文件中读入问题的实例,寻路问题 + In problemInput = new In("resources/pathfinding.txt"); + + //生成一个具体的EngineFeeder:FeederXu,引擎饲养员徐老师:) + EngineFeeder feeder = new MyFeeder(); + + //feeder从文件获取所有问题实例 + ArrayList problems = feeder.getProblems(problemInput); + + //从Feeder获取所使用的搜索引擎 AStar + /* + BestFirstSearch astar = (BestFirstSearch) feeder.getScoreSearcher(); + for (Problem problem : problems){ + Stopwatch stopwatch = new Stopwatch(); + //使用AStar引擎求解问题 + Deque path = astar.search(problem); + //解的可视化 + problem.showSolution(path); + //仅打印路径 + problem.printPath(path); + System.out.println(astar.expandedNode()); + System.out.println(path.size()); + System.out.println(stopwatch.elapsedTime()); + } + System.out.println("=============================================================="); + */ + //从Feeder获取所使用的搜索引擎 IDAStar + + IDAStarSearch idastar = (IDAStarSearch) feeder.getIdaStar(); + for (Problem problem : problems){ + Stopwatch stopwatch = new Stopwatch(); + //使用AStar引擎求解问题 + Deque path = idastar.search(problem); + //解的可视化 + problem.showSolution(path); + //仅打印路径 + //problem.printPath(path); + System.out.println(path.size()); + System.out.println(stopwatch.elapsedTime()); + System.out.println("=============================================================="); + } + + //从Feeder获取所使用的搜索引擎 Dijkstra + /* + BestFirstSearch dijkstra = (BestFirstSearch) feeder.getDijkstra(); + for (Problem problem : problems){ + //使用AStar引擎求解问题 + Deque path = dijkstra.search(problem); + //解的可视化 + problem.showSolution(path); + //仅打印路径 + problem.printPath(path); + System.out.println(dijkstra.expandedNode()); + System.out.println(); + }*/ + } +} \ No newline at end of file diff --git a/SearchFramework1.0.1/src/core/solver/Node.java b/SearchFramework1.0.1/src/core/solver/Node.java new file mode 100644 index 0000000..d3a7221 --- /dev/null +++ b/SearchFramework1.0.1/src/core/solver/Node.java @@ -0,0 +1,149 @@ +package core.solver; + +import core.problem.Action; +import core.problem.State; +import core.solver.heuristic.EvaluationType; +import core.solver.heuristic.Predictor; + +import java.util.Comparator; +import java.util.EnumMap; + +import static core.solver.heuristic.EvaluationType.*; + +public final class Node{ + + //不考虑路径代价的Node + + /** + * + * @param state 当前结点 + * @param parent 父结点 + * @param action 从父结点到当前结点所采取的Action + */ + public Node(State state, Node parent, Action action){ + this(state, parent, action, 0, 0); + } + + //考虑路径代价的Node + + /** + * + * @param state 当前结点 + * @param parent 父结点 + * @param action 从父结点到当前结点所采取的Action + * @param pathCost 从根结点到当前结点的耗散值 + * @param heuristic 从当前结点到目标结点的距离估计值 + */ + public Node(State state, Node parent, Action action, int pathCost, int heuristic) { + super(); + this.state = state; + this.parent = parent; + this.action = action; + this.pathCost = pathCost; + this.heuristic = heuristic; + } + + /** + * + * @param action:当前结点状态所使用的Action + * @param predictor:用于计算h值的启发函数 + * @param goal: 作为启发函数的参数,用于计算子结点状态的h值 + * @return 当前结点的子结点 + */ + public Node childNode(Action action, Predictor predictor, State goal) { + return new Node(state.next(action), this, action, + pathCost + action.stepCost(), + predictor.heuristics(state, goal)); + } + + private final State state; // the state in the state space to which the node corresponds + private final Node parent; // the node in the search tree which generated this node + + public Action getAction() { + return action; + } + + private final Action action; // the action that was applied to the parent to generate the node + private final int pathCost; // the cost of the path from the initial state to this node + private final int heuristic; // estimated cost of the cheapest path from the state of this node to a goal state + + //返回当前Node的f值 f = g + h + public int evaluation() + { + return pathCost + heuristic; + } + + public State getState() { + return state; + } + + public Node getParent() { + return parent; + } + + public int getPathCost() { + return pathCost; + } + + public int getHeuristic() { + return heuristic; + } + + /** + * Node的状态相同,即认为他们是相同的 + */ + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + + if (obj instanceof Node) { + Node another = (Node) obj; + //两个Node对象的状态相同,则认为是相同的 + return this.getState().equals(another.getState()); + } + return false; + //Node another = (Node) obj; + //return obj == this || this.getState().equals(another.getState()); + } + + public void draw() { + System.out.println(this); + } + + /** + * 不同估值函数的枚举映射表 + */ + private static final EnumMap> evaluators = new EnumMap<>(EvaluationType.class); + //枚举映射表的初始化 + static{ + //f = g + h FULL + evaluators.put(FULL, + Comparator.comparingInt(Node::evaluation) + ); + + //g PATH_COST + evaluators.put(PATH_COST, + Comparator.comparingInt(Node::getPathCost) + ); + + //h HEURISTIC + evaluators.put(HEURISTIC, + Comparator.comparingInt(Node::getHeuristic) + ); + } + + /** + * + * @param type 结点评估器的类型 + * @return 相关类型的结点评估器 + */ + public static Comparator evaluator(EvaluationType type) { + return evaluators.get(type); + } + + @Override + public String toString() { + return "[" + state.toString() + "⬅" + "[" + parent.getState().toString() + ", " + action.toString() + "], " + pathCost + ", " + heuristic + "]"; + } + +} diff --git a/SearchFramework1.0.1/src/core/solver/Searcher.java b/SearchFramework1.0.1/src/core/solver/Searcher.java new file mode 100644 index 0000000..2ee6875 --- /dev/null +++ b/SearchFramework1.0.1/src/core/solver/Searcher.java @@ -0,0 +1,29 @@ +package core.solver; + +import core.problem.Problem; +import java.util.ArrayDeque; +import java.util.Deque; + +public interface Searcher { + + /** + * @problem 要解决的问题 + * @return 当前问题的解路径。如果没有解,则返回null + */ + Deque search(Problem problem); + + /** + * 默认实现,从目标结点,反向回溯得到一条路径 + * @param node 目标结点 + * @return 倒推生成的从根结点到目标结点的路径,栈底是目标结点,栈顶是根结点 + */ + default Deque generatePath(Node node) { + Deque stack = new ArrayDeque<>(); + + while (node.getParent() != null) { + stack.push(node); + node = node.getParent(); + } + return stack; + } +} \ No newline at end of file diff --git a/SearchFramework1.0.1/src/core/solver/blinded/BreadthFirstSearch.java b/SearchFramework1.0.1/src/core/solver/blinded/BreadthFirstSearch.java new file mode 100644 index 0000000..5718576 --- /dev/null +++ b/SearchFramework1.0.1/src/core/solver/blinded/BreadthFirstSearch.java @@ -0,0 +1,4 @@ +package core.solver.blinded; + +public class BreadthFirstSearch { +} diff --git a/SearchFramework1.0.1/src/core/solver/blinded/DepthFirstSearch.java b/SearchFramework1.0.1/src/core/solver/blinded/DepthFirstSearch.java new file mode 100644 index 0000000..4783a88 --- /dev/null +++ b/SearchFramework1.0.1/src/core/solver/blinded/DepthFirstSearch.java @@ -0,0 +1,4 @@ +package core.solver.blinded; + +public class DepthFirstSearch { +} diff --git a/SearchFramework1.0.1/src/core/solver/heuristic/AbstractFrontier.java b/SearchFramework1.0.1/src/core/solver/heuristic/AbstractFrontier.java new file mode 100644 index 0000000..08a2163 --- /dev/null +++ b/SearchFramework1.0.1/src/core/solver/heuristic/AbstractFrontier.java @@ -0,0 +1,70 @@ +package core.solver.heuristic; + +import core.problem.State; +import core.solver.Node; + +import java.util.*; + +/** + * AbstractQueue的子类, + * 其存放的元素的类型为 core.solver.Node + */ +public abstract class AbstractFrontier extends AbstractQueue { + + public AbstractFrontier(Comparator evaluator) { + this.evaluator = evaluator; + } + + public Comparator getEvaluator() { + return evaluator; + } + + // 节点优先级比较器,在Node类中定义了三个不同的比较器(Dijkstra, Greedy Best-First, and Best-First) + // 不同的选择对应不同的算法。 + protected final Comparator evaluator; + + /** + * 获取 Frontier 中,状态为 s 的节点 + * @param s 状态 + * @return 存在: 相应的状态为 s 的节点; + * 不存在:null + */ + protected abstract Node getNode(State s); + + /** + * 如果Frontier中已经存在与node状态相同的结点, + * 则舍弃掉二者之间不好的那一个。 + * @param node 结点 + * @return 插入成功返回true + */ + public final boolean discardOrReplace(Node node){ + if (node == null) + throw new NullPointerException(); + + //结点node是否出现在frontier中; null: not revisited + Node oldNode = getNode(node.getState()); + //如果oldNode为null,则当前结点node的状态不在Frontier中,那么肯定在explored表中, + // 又因为h函数是consistent的,所以discard + //如果oldNode不为null,则在oldNode已经在Frontier中,并且旧的估值比新的大,即新生成的结点更好 + if (oldNode != null && evaluator.compare(oldNode, node) > 0){ + //则,用新节点替换旧节点 + replace(oldNode, node); + } + return true; + } + + /** + * 用节点 e 替换掉具有相同状态的旧节点 oldNode + * + * @param oldNode 被替换的结点 + * @param newNode 新结点 + */ + public void replace(Node oldNode, Node newNode) { + this.remove(oldNode); + this.add(newNode); + } + + public boolean contains(Node node) { + return false; + } +} diff --git a/SearchFramework1.0.1/src/core/solver/heuristic/BestFirstSearch.java b/SearchFramework1.0.1/src/core/solver/heuristic/BestFirstSearch.java new file mode 100644 index 0000000..efde515 --- /dev/null +++ b/SearchFramework1.0.1/src/core/solver/heuristic/BestFirstSearch.java @@ -0,0 +1,77 @@ +package core.solver.heuristic; + +import java.util.*; + +import core.problem.Problem; +import core.problem.State; +import core.solver.*; +import g04.problem.npuzzle.PuzzleState; + +/** + * 不能被继承的类,final类 + */ +public final class BestFirstSearch implements Searcher { + + //已经访问过的节点集合 + private final Set explored; + + //还未扩展的节点队列 + private final AbstractFrontier frontier; + + private final Predictor predictor; + /** + * 构造函数 + * @param explored 具体的状态类的Set hashSet + * @param frontier Node对象的一个优先队列,可以确定一个状态所对应的结点是否在frontier中, + */ + public BestFirstSearch(Set explored, AbstractFrontier frontier, Predictor predictor) { + this.explored = explored; + this.frontier = frontier; + this.predictor = predictor; + } + + @Override + public Deque search(Problem problem) + { + //如果可直接判断问题是否可解,无解时直接返回解路径为null + if (!problem.solvable()){ + return null; + } + frontier.clear(); + explored.clear(); + //搜索树的根节点 + Node root = problem.root(predictor); + this.frontier.add(root); + //int i = 0; + while (true) { + if (frontier.isEmpty()) + return null; //失败 + Node node = frontier.poll(); //choose the lowest-cost node in frontier + //如果已经到达目标状态, + if (problem.goal(node.getState())) { + return generatePath(node); + } + //将当前结点放入explored表中 + explored.add(node.getState()); + //System.out.println(i++); + for (Node child : problem.childNodes(node, predictor)) { + // 如果新扩展的节点,没有在Explored和Fringe中出现过。 + // 因为两个node的状态相同,则视为二者相同(equals函数), + // 所以contains函数判断frontier中是否存在跟child的状态相同的结点 + if (!explored.contains(child.getState()) && !frontier.contains(child)) { + frontier.offer(child); + } + else { + //child出现在Explored或Fringe中 + //在启发函数满足单调条件的前提下,如果child是出现在Explored表里的节点,肯定不在Fringe中; + //而且到达这个节点的新路径肯定不会比旧路径更优 + frontier.discardOrReplace(child); + } + } + } + } + + public int expandedNode(){ + return explored.size(); + } +} \ No newline at end of file diff --git a/SearchFramework1.0.1/src/core/solver/heuristic/EvaluationType.java b/SearchFramework1.0.1/src/core/solver/heuristic/EvaluationType.java new file mode 100644 index 0000000..46e7981 --- /dev/null +++ b/SearchFramework1.0.1/src/core/solver/heuristic/EvaluationType.java @@ -0,0 +1,11 @@ +package core.solver.heuristic; + +/** + * Best-First搜索的三类不同的估值策略 + * 对所有问题都是通用的 + */ +public enum EvaluationType { + FULL, + PATH_COST, + HEURISTIC //对于不同的问题,启发策略又可能又多种。 +} diff --git a/SearchFramework1.0.1/src/core/solver/heuristic/Predictor.java b/SearchFramework1.0.1/src/core/solver/heuristic/Predictor.java new file mode 100644 index 0000000..436d0cb --- /dev/null +++ b/SearchFramework1.0.1/src/core/solver/heuristic/Predictor.java @@ -0,0 +1,18 @@ +package core.solver.heuristic; + +import core.problem.State; + +/** + * + * + */ +public interface Predictor { + /** + * + * @param + * state 被评估的状态 + * goal 目标状态 + * @return 该状态到目标状态的启发值 + */ + int heuristics(State state, State goal); +} diff --git a/SearchFramework1.0.1/src/g04/problem/npuzzle/MyFeeder.java b/SearchFramework1.0.1/src/g04/problem/npuzzle/MyFeeder.java new file mode 100644 index 0000000..3eb4718 --- /dev/null +++ b/SearchFramework1.0.1/src/g04/problem/npuzzle/MyFeeder.java @@ -0,0 +1,84 @@ +package g04.problem.npuzzle; + +import algs4.util.In; +import core.problem.Problem; +import core.runner.EngineFeeder; +import core.runner.HeuristicType; +import core.solver.Node; +import core.solver.Searcher; +import core.solver.heuristic.AbstractFrontier; +import core.solver.heuristic.EvaluationType; +import core.solver.heuristic.Predictor; +import g04.solver.heuristic.IDAStarSearch; +import g04.solver.heuristic.MyFrontier; + +import java.util.ArrayList; +import java.util.Scanner; + +public class MyFeeder extends EngineFeeder { + /** + * 从文件中读取所有的NPuzzle问题 + * @param io 输入流 + * @return 所有的NPuzzle问题 + */ + @Override + public ArrayList getProblems(In io) { + ArrayList problems = new ArrayList(); + while (io.hasNextLine()){ + //棋盘大小 + int size = io.readInt(); + int[][] board = new int[size][size]; + //读入初始状态 + for (int i = 0; i < size; i++) + for (int j = 0; j < size; j++) + board[i][j] = io.readInt(); + PuzzleState initState = new PuzzleState(board, size); + //读入目标状态 + for (int i = 0; i < size; i++) + for (int j = 0; j < size; j++) + board[i][j] = io.readInt(); + PuzzleState goal = new PuzzleState(board, size); + Puzzle puzzleProblem = new Puzzle(initState, goal, size); + //添加到问题列表 + problems.add(puzzleProblem); + } + return problems; + } + + @Override + public ArrayList getProblems(Scanner scanner) { + return null; + } + + @Override + public AbstractFrontier getFrontier(EvaluationType type) { + return new MyFrontier(Node.evaluator(type)); + } + + /** + * 获取对应的启发函数 + * @param type 估值函数的类型 + * @return 对应的启发函数 + */ + @Override + public Predictor getPredictor(HeuristicType type) { + return PuzzleState.predictor(type); + } + + /** + * 获取IDA*算法的搜索器 + * @return IDA*算法的搜索器 + */ + @Override + public Searcher getIdaStar() { + return new IDAStarSearch(PuzzleState.predictor(HeuristicType.MANHATTAN)); + } + + /** + * @return A*算法的搜索器 + */ + @Override + public Searcher getScoreSearcher() { + return getAStar(HeuristicType.MANHATTAN); + } +} diff --git a/SearchFramework1.0.1/src/g04/problem/npuzzle/Puzzle.java b/SearchFramework1.0.1/src/g04/problem/npuzzle/Puzzle.java new file mode 100644 index 0000000..f3520f9 --- /dev/null +++ b/SearchFramework1.0.1/src/g04/problem/npuzzle/Puzzle.java @@ -0,0 +1,155 @@ +package g04.problem.npuzzle; + +import core.problem.Action; +import core.problem.Problem; +import core.problem.State; +import core.solver.Node; +import core.solver.heuristic.Predictor; + +import java.util.ArrayList; +import java.util.Deque; +import java.util.Random; + +public class Puzzle extends Problem { + + //Zobrist哈希随机值 + public static int[][][] Zobrist; + //目标状态到默认状态的曼哈顿距离(默认状态为按顺序放置位将牌,空格最后) + public static int[][][] goalmanhattan; + + /** + * 构造函数 + * @param initialState 初始状态 + * @param goal 目标状态 + * @param size 棋盘大小 + */ + public Puzzle(State initialState, State goal, int size) { + super(initialState, goal, size); + Random r = new Random(); + goalmanhattan = new int[size][size][2]; + Zobrist = new int[size][size][size * size]; + for(int i = 0; i < size; i++) { + for(int j = 0; j < size; j++) { + goalmanhattan[i][j][0] = (((PuzzleState)goal).getBoardAt(i, j) - 1) / size;; + goalmanhattan[i][j][1] = (((PuzzleState)goal).getBoardAt(i, j) - 1) % size;;; + for(int k = 0; k < size * size; k++) { + Zobrist[i][j][k] = r.nextInt(); + } + } + } + } + + /** + * + * @param i 行坐标 + * @param j 列坐标 + * @param state 状态 + * @return 该状态对应位置处的Zobrist随机值 + */ + public static int getZobristAt(int i, int j, int state) { + return Zobrist[i][j][state]; + } + + /** + * 比较两个状态的奇偶性是否相等 + * @return + */ + @Override + public boolean solvable() { + return ((PuzzleState)initialState).parity() == ((PuzzleState)goal).parity(); + } + + @Override + public int stepCost(State state, Action action) { + return 1; + } + + /** + * + * @param state 当前状态 + * @param action 当前状态下所采用的动作 + * @return 当前action是否可行,true: 可行,false: 不可行 + */ + @Override + protected boolean applicable(State state, Action action) { + //获取action对应的位移量 + int[] next = ((PuzzleAction)action).getNext(); + //空白位移动后是否越界 + int row = ((PuzzleState)state).getBlank(0) + next[0]; + int col = ((PuzzleState)state).getBlank(1) + next[1]; + return row >= 0 && row < size && col >= 0 && col < size; + } + + @Override + public void showSolution(Deque path) { + + } + + /** + * 输出初始状态和目标状态 + */ + @Override + public void draw() { + initialState.draw(); + System.out.println(); + goal.draw(); + } + + /** + * 打印解路径 + * @param path 解路径 + */ + @Override + public void printPath(Deque path) { + if (path == null){ + System.out.println("No Solution."); + return; + } + initialState.draw(); + for (Node node : path) { + PuzzleAction puzzleAction = (PuzzleAction) node.getAction(); + puzzleAction.draw(); + PuzzleState puzzleState = (PuzzleState) node.getState(); + puzzleState.draw(); + } + System.out.println(); + } + + public final Iterable childs(Node parent) { + ArrayList nodes = new ArrayList<>(); + //父结点的状态 + State parentState = parent.getState(); + //对于parentState上所有可能的action,但有的不可行 + //parentState.draw(); + for (Action action : parentState.actions()){ + //如果父结点状态下的动作是可行的 + if (applicable(parentState, action)){ + //得到后继状态 + State state = parentState.next(action); + //计算路径长度 = 父结点路径长度 + 进入后继状态所采取的动作的代价 + int pathCost = parent.getPathCost() + stepCost(state, action); + //根据曼哈顿距离特性,只需要计算被移动的位将牌改变的曼哈顿距离 + int heuristics = parent.getHeuristic() - nextManhattan((PuzzleState)parentState, (PuzzleState)state); + //生成子结点 + Node child = new Node(state, parent, action, pathCost, heuristics); + nodes.add(child); + } + } + return nodes; + } + + /** + * 计算被移动的位将牌改变的曼哈顿距离 + * @param parent 父状态 + * @param child 子状态 + * @return 改变的曼哈顿距离 + */ + public int nextManhattan(PuzzleState parent, PuzzleState child) { + //被移动的位将牌对应数字 + int n = parent.getBoardAt(child.getBlank(0), child.getBlank(1)); + int x = (n - 1) / size; + int y = (n - 1) % size; + return Math.abs(goalmanhattan[x][y][0] - child.getBlank(0)) + Math.abs(goalmanhattan[x][y][1] - child.getBlank(1)) + - Math.abs(goalmanhattan[x][y][0] - parent.getBlank(0)) - Math.abs(goalmanhattan[x][y][1] - parent.getBlank(1)); + } +} diff --git a/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleAction.java b/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleAction.java new file mode 100644 index 0000000..26e5fc6 --- /dev/null +++ b/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleAction.java @@ -0,0 +1,40 @@ +package g04.problem.npuzzle; + +import core.problem.Action; + +public class PuzzleAction extends Action { + + /* + * 移动一步 + * 0: Up, 1: Right, 2: Down, 3: Right + */ + private final int dir; + // 移动方向 + private static final char[] direction = {'R', 'D', 'L', 'U'}; + private static final int[][] next = { + {0, 1}, {1, 0}, {0, -1}, {-1, 0} + }; + + public PuzzleAction(int dir) { + this.dir = dir; + } + + public int[] getNext() { + return next[dir]; + } + + /** + * 打印输出action + */ + @Override + public void draw() { + System.out.println(" ↓"); + System.out.println(" ↓-(#, " + direction[dir] + ")"); + System.out.println(" ↓"); + } + + @Override + public int stepCost() { + return 1; + } +} diff --git a/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleState.java b/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleState.java new file mode 100644 index 0000000..43588c4 --- /dev/null +++ b/SearchFramework1.0.1/src/g04/problem/npuzzle/PuzzleState.java @@ -0,0 +1,252 @@ +/** + * + */ +package g04.problem.npuzzle; + +import core.problem.Action; +import core.problem.State; +import core.runner.HeuristicType; +import core.solver.heuristic.Predictor; +import xu.problem.pathfinding.Direction; +import xu.problem.pathfinding.Move; +import xu.problem.pathfinding.Position; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.Objects; +import java.util.Scanner; + + +/** + * 类描述: + * 作者: wanwenlong + * 创建日期:2021年3月28日 + * 修改人: + * 修改日期: + * 修改内容: + * 版本号: 1.0.0 + */ +public class PuzzleState extends State { + + private final int size; + //该状态每个位置的位将牌数字 + private final int[][] board; + //空格对应位置 + private int[] blank; + + /** + * 构造函数 + */ + public PuzzleState(int[][] board, int size) { + this.size = size; + this.board = new int[size][size]; + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + this.board[i][j] = board[i][j]; + if (board[i][j] == 0) + this.blank = new int[]{i, j}; + } + } + } + + /** + * 拷贝构造 + */ + public PuzzleState(PuzzleState puzzleState) { + this.size = puzzleState.size; + this.board = new int[size][size]; + for (int i = 0; i < size; i++) { + System.arraycopy(puzzleState.board[i], 0, this.board[i], 0, size); + } + this.blank = new int[]{puzzleState.blank[0], puzzleState.blank[1]}; + } + + public int getSize() { + return size; + } + + public int getBoardAt(int i, int j) { + return board[i][j]; + } + + public int getBoardAt(int i) { + return board[i/size][i%size]; + } + + public int getBlank(int i) { + return blank[i]; + } + + /** + * 输出当前状态 + */ + @Override + public void draw() { + drawLine(); + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + System.out.print("| " + String.valueOf(board[i][j]) + " "); + } + System.out.println("|"); + drawLine(); + } + } + + /** + * 画线 + */ + public void drawLine() { + for (int i = 0; i < size; i++) + System.out.print("+---"); + System.out.println("+"); + } + + /** + * 当前状态采用action而进入的下一个状态 + * @param action + * @return + */ + @Override + public State next(Action action) { + PuzzleState nextState = new PuzzleState(this); + int[] next = ((PuzzleAction)action).getNext(); + nextState.blank[0] += next[0]; + nextState.blank[1] += next[1]; + nextState.board[this.blank[0]][this.blank[1]] = this.board[nextState.blank[0]][nextState.blank[1]]; + nextState.board[nextState.blank[0]][nextState.blank[1]] = 0; + return nextState; + } + + /** + * 当前状态下可以采用的所有Action + * @return 所有Action + */ + @Override + public Iterable actions() { + ArrayList actions = new ArrayList(); + for (int d = 0; d < 4; d++) + actions.add(new PuzzleAction(d)); + return actions; + } + + /** + * NPuzzle状态的奇偶性 + * @return 1:奇 0:偶 + */ + public int parity() { + int n = (size % 2 == 0) ? blank[0] + 1 : 0; + for (int i = 0; i < size * size; i++) { + for (int j = 0; j < i; j++) { + if (this.getBoardAt(i) != 0 && this.getBoardAt(j) != 0 && this.getBoardAt(i) < this.getBoardAt(j)) + n++; + } + } + return n % 2; + } + + @Override + public boolean equals(Object obj) { + for (int i = 0; i < size * size - 1; i++) { + if (this.getBoardAt(i) != ((PuzzleState) obj).getBoardAt(i)) + return false; + } + return true; + //return this.hashCode() == obj.hashCode(); + } + + /** + * Zobrist哈希 + * @return 哈希值 + */ + @Override + public int hashCode() { + int hash = 0; + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + hash ^= Puzzle.getZobristAt(i, j, board[i][j]); + } + } + return hash; + } + + //枚举映射,存放不同类型的启发函数 + private static final EnumMap predictors = new EnumMap<>(HeuristicType.class); + static{ + predictors.put(HeuristicType.MISPLACED, + (state, goal) -> ((PuzzleState)state).misPlaced((PuzzleState)goal)); + predictors.put(HeuristicType.MANHATTAN, + (state, goal) -> ((PuzzleState)state).manhattan((PuzzleState)goal)); + predictors.put(HeuristicType.DISJOINT_PATTERN, + (state, goal) -> ((PuzzleState)state).disjointPattern((PuzzleState)goal)); + } + public static Predictor predictor(HeuristicType type){ + return predictors.get(type); + } + + /** + * 不在位将牌 + */ + private int misPlaced(PuzzleState goal) { + int heuristics = 0; + int size = goal.getSize(); + for (int i = 0; i < size * size - 1; i++) { + if (this.getBoardAt(i) != 0 && this.getBoardAt(i) != goal.getBoardAt(i)) + heuristics++; + } + return heuristics; + } + + /** + * 曼哈顿距离 + */ + private int manhattan(PuzzleState goal) { + int heuristics = 0; + int[][][] m = new int[size][size][2]; + int x, y; + //第一步,计算当前状态到默认状态曼哈顿距离 + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + if (this.board[i][j] == 0) + continue; + x = (this.board[i][j] - 1) / size; + y = (this.board[i][j] - 1) % size; + m[x][y][0] = x - i; + m[x][y][1] = y - j; + } + } + //第二步,计算默认状态到目标状态曼哈顿距离 + //结合两步即为当前状态到目标状态曼哈顿距离 + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + if (goal.board[i][j] == 0) + continue; + x = (goal.board[i][j] - 1) / size; + y = (goal.board[i][j] - 1) % size; + heuristics += Math.abs(m[x][y][0] + i - x) + Math.abs(m[x][y][1] + j - y); + } + } + return heuristics; + } + + /** + * Disjoint pattern heuristic + */ + private int disjointPattern(PuzzleState goal) { + return 0; + } + + public static void main(String[] args) { + int[][] a = new int[][]{{8, 13, 0, 6}, {1, 15, 9, 14}, {3, 4, 5, 11}, {7, 2, 10, 12}}; + int[][] g = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 0}}; + PuzzleState puzzleState = new PuzzleState(a, 4); + int n = 0; + for (int i = 0; i < 4 * 4; i++) { + for (int j = 0; j < i; j++) { + if (puzzleState.getBoardAt(i) != 0 && puzzleState.getBoardAt(j) != 0 && puzzleState.getBoardAt(i) < puzzleState.getBoardAt(j)) + n++; + } + System.out.println(n); + } + System.out.println(n); + } +} \ No newline at end of file diff --git a/SearchFramework1.0.1/src/g04/solver/heuristic/IDAStarSearch.java b/SearchFramework1.0.1/src/g04/solver/heuristic/IDAStarSearch.java new file mode 100644 index 0000000..3bdebab --- /dev/null +++ b/SearchFramework1.0.1/src/g04/solver/heuristic/IDAStarSearch.java @@ -0,0 +1,65 @@ +package g04.solver.heuristic; + +import core.problem.Problem; +import core.solver.Node; +import core.solver.Searcher; +import core.solver.heuristic.Predictor; +import g04.problem.npuzzle.Puzzle; + +import java.util.Deque; +import java.util.Stack; + +public class IDAStarSearch implements Searcher { + + private final Predictor predictor; + + //裁剪阈值 + private int cutoff; + //下一轮迭代的裁剪阈值 + private int newCutoff; + //最大迭代深度 + private int maxIteratorDepth = 256; + + private final Stack openStack; + private final Stack closeStack; + + public IDAStarSearch(Predictor predictor) { + this.predictor = predictor; + openStack = new Stack(); + closeStack = new Stack(); + } + + @Override + public Deque search(Problem problem) { + //获取根节点 + openStack.clear(); + Node root = problem.root(predictor); + cutoff = root.evaluation(); + while (cutoff < maxIteratorDepth) { + openStack.push(root); + newCutoff = cutoff; + //当栈未空时继续,执行带裁剪值的深度优先搜索 + while (!openStack.empty()) { + Node node = openStack.pop(); + //更新裁剪值为未被探索节点中最小的评估值 + newCutoff = (newCutoff > cutoff) ? (Math.min(node.evaluation(), newCutoff)) : node.evaluation(); + if (problem.goal(node.getState())) { + return generatePath(node); + } + //当小于等于裁剪值时,继续向深处搜索 + if (node.evaluation() <= cutoff) { + for (Node child : ((Puzzle)problem).childs(node)) { + //剪枝,防止节点探索回到父节点 + if (node.getParent() == null || !node.getParent().equals(child)) { + openStack.push(child); + } + } + } + } + //更新裁剪值 + cutoff = newCutoff; + //System.out.println(cutoff); + } + return null; + } +} diff --git a/SearchFramework1.0.1/src/g04/solver/heuristic/MyFrontier.java b/SearchFramework1.0.1/src/g04/solver/heuristic/MyFrontier.java new file mode 100644 index 0000000..43aa3b1 --- /dev/null +++ b/SearchFramework1.0.1/src/g04/solver/heuristic/MyFrontier.java @@ -0,0 +1,125 @@ +package g04.solver.heuristic; + +import core.problem.State; +import core.solver.Node; +import core.solver.heuristic.AbstractFrontier; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.PriorityQueue; + +/** + * S18020031073开发的”超级棒“的Frontier数据结构 + */ +public class MyFrontier extends AbstractFrontier { + + /** + * 优先队列,节点根据评估值排序 + */ + PriorityQueue frontier = new PriorityQueue(new Comparator(){ + public int compare(Node a, Node b){ + return evaluator.compare(a, b); + } + }); + //增加Map集合,使得节点的查找时间复杂度降低至O(1) + HashMap hashMap=new HashMap(); + + /** + * + * @param comparator + */ + public MyFrontier(Comparator comparator) { + super(comparator); + } + + /** + * 获取 Frontier 中,状态为 s 的节点 + * + * @param s 状态 + * @return 存在: 相应的状态为 s 的节点; + * 不存在:null + */ + @Override + protected Node getNode(State s) { + return hashMap.get(s.hashCode()); + } + + /** + * 用节点 e 替换掉具有相同状态的旧节点 oldNode + * + * @param oldNode + * @param e + */ + @Override + public void replace(Node oldNode, Node e) { + hashMap.put(oldNode.getState().hashCode(), e); + //frontier.remove(oldNode); + frontier.offer(e); + } + + /** + * Returns an iterator over the elements contained in this collection. + * + * @return an iterator over the elements contained in this collection + */ + @Override + public Iterator iterator() { + return frontier.iterator(); + } + + @Override + public int size() { + return frontier.size(); + } + + /** + * Inserts the specified element into this queue if it is possible to do + * so immediately without violating capacity restrictions. + * When using a capacity-restricted queue, this method is generally + * preferable to {@link #add}, which can fail to insert an element only + * by throwing an exception. + * + * @param node the element to add + * @return {@code true} if the element was added to this queue, else + * {@code false} + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null and + * this queue does not permit null elements + * @throws IllegalArgumentException if some property of this element + * prevents it from being added to this queue + */ + @Override + public boolean offer(Node node) { + hashMap.put(node.getState().hashCode(), node); + frontier.offer(node); + return true; + } + + @Override + public Node poll(){ + try { + Node node = frontier.poll(); + hashMap.remove(node.getState().hashCode()); + return node; + } catch (Exception e) { + } + return null; + } + + @Override + public Node peek() { + return frontier.peek(); + } + + /** + * 判断是否含有该节点 + * @param node + * @return + */ + @Override + public boolean contains(Node node) { + return hashMap.get(node.getState().hashCode()) != null; + } +} diff --git a/SearchFramework1.0.1/src/g04/solver/heuristic/VeryEffecientFrontier.java b/SearchFramework1.0.1/src/g04/solver/heuristic/VeryEffecientFrontier.java new file mode 100644 index 0000000..575e296 --- /dev/null +++ b/SearchFramework1.0.1/src/g04/solver/heuristic/VeryEffecientFrontier.java @@ -0,0 +1,147 @@ +package g04.solver.heuristic; + +import core.problem.State; +import core.solver.Node; +import core.solver.heuristic.AbstractFrontier; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; + +/** + * S18020031073开发的”超级棒“的Frontier数据结构 + */ +public class VeryEffecientFrontier extends AbstractFrontier { + + /** + * My secret wonderful data structures! :) + * + */ + ArrayList frontier = new ArrayList(); + HashMap hashMap=new HashMap(); + + /** + * + * @param comparator + */ + public VeryEffecientFrontier(Comparator comparator) { + super(comparator); + } + + /** + * 获取 Frontier 中,状态为 s 的节点 + * + * @param s 状态 + * @return 存在: 相应的状态为 s 的节点; + * 不存在:null + */ + @Override + protected Node getNode(State s) { + /*for (Node node : frontier) { + if (node.getState().equals(s)) { + return node; + } + } + return null;*/ + return hashMap.get(s.hashCode()); + } + + /** + * 用节点 e 替换掉具有相同状态的旧节点 oldNode + * + * @param oldNode + * @param e + */ + @Override + public void replace(Node oldNode, Node e) { + //hashMap.put(oldNode.getState().hashCode(), e); + //frontier.set(frontier.indexOf(oldNode), e); + this.remove(oldNode); + this.offer(e); + } + + /** + * Returns an iterator over the elements contained in this collection. + * + * @return an iterator over the elements contained in this collection + */ + @Override + public Iterator iterator() { + return frontier.iterator(); + } + + @Override + public int size() { + return frontier.size(); + } + + /** + * Inserts the specified element into this queue if it is possible to do + * so immediately without violating capacity restrictions. + * When using a capacity-restricted queue, this method is generally + * preferable to {@link #add}, which can fail to insert an element only + * by throwing an exception. + * + * @param node the element to add + * @return {@code true} if the element was added to this queue, else + * {@code false} + * @throws ClassCastException if the class of the specified element + * prevents it from being added to this queue + * @throws NullPointerException if the specified element is null and + * this queue does not permit null elements + * @throws IllegalArgumentException if some property of this element + * prevents it from being added to this queue + */ + @Override + public boolean offer(Node node) { + int j = 0; + for (Node value : frontier) { + if (evaluator.compare(value, node) >= 0) { + break; + } + j++; + } + frontier.add(j, node); + hashMap.put(node.getState().hashCode(), node); + return true; + } + + @Override + public Node poll(){ + try { + Node node = frontier.get(0); + frontier.remove(0); + hashMap.remove(node.getState().hashCode()); + return node; + } catch (Exception e) { + } + return null; + } + + @Override + public Node peek() { + try { + return frontier.get(0); + } catch (Exception e) { + } + return null; + } + + @Override + public boolean contains(Node node) { + /*for (Node oldNode : frontier) { + if (oldNode.equals(node)) { + return true; + } + } + return false;*/ + return hashMap.get(node.getState().hashCode()) != null; + } + + public void remove(Node node) { + //frontier.remove(node); + hashMap.remove(node.getState().hashCode()); + } + +} diff --git a/SearchFramework1.0.1/src/xu/problem/pathfinding/Direction.java b/SearchFramework1.0.1/src/xu/problem/pathfinding/Direction.java new file mode 100644 index 0000000..e5d0f90 --- /dev/null +++ b/SearchFramework1.0.1/src/xu/problem/pathfinding/Direction.java @@ -0,0 +1,60 @@ +package xu.problem.pathfinding; + +import java.util.EnumMap; + +public enum Direction { + N('↑'), //北 + NE('↗'), //东北 + E('→'), //东 + SE('↘'), //东南 + S('↓'), //南 + SW('↙'), //西南 + W('←'), //西 + NW('↖'); //西北 + + Direction(char symbol){ + this.symbol = symbol; + } + private final char symbol; + public char symbol(){ + return symbol; + } + + //各个方向移动的代价,直线为10,斜线为14 + private static final EnumMap DIRECTION_COST = new EnumMap<>(Direction.class); + static{ + int scale = Position.SCALE; + int diagonal = (int) (scale * Position.ROOT2); + + DIRECTION_COST.put(N, scale); + DIRECTION_COST.put(NE, diagonal); + DIRECTION_COST.put(E, scale); + DIRECTION_COST.put(SE, diagonal); + DIRECTION_COST.put(S, scale); + DIRECTION_COST.put(SW, diagonal); + DIRECTION_COST.put(W, scale); + DIRECTION_COST.put(NW, diagonal); + } + + //各个方向移动的坐标位移量 + private static final EnumMap DIRECTION_OFFSET = new EnumMap<>(Direction.class); + static{ + //列号(或横坐标)增加量;行号(或纵坐标)增加量 + DIRECTION_OFFSET.put(N, new int[]{0, -1}); + DIRECTION_OFFSET.put(NE, new int[]{1, -1}); + DIRECTION_OFFSET.put(E, new int[]{1, 0}); + DIRECTION_OFFSET.put(SE, new int[]{1, 1}); + DIRECTION_OFFSET.put(S, new int[]{0, 1}); + DIRECTION_OFFSET.put(SW, new int[]{-1, 1}); + DIRECTION_OFFSET.put(W, new int[]{-1, 0}); + DIRECTION_OFFSET.put(NW, new int[]{-1, -1}); + } + + public static int[] offset(Direction dir){ + return DIRECTION_OFFSET.get(dir); + } + + public static int cost(Direction dir){ + return DIRECTION_COST.get(dir); + } +} diff --git a/SearchFramework1.0.1/src/xu/problem/pathfinding/FeederXu.java b/SearchFramework1.0.1/src/xu/problem/pathfinding/FeederXu.java new file mode 100644 index 0000000..0517ed0 --- /dev/null +++ b/SearchFramework1.0.1/src/xu/problem/pathfinding/FeederXu.java @@ -0,0 +1,109 @@ +package xu.problem.pathfinding; + +import algs4.util.In; +import core.problem.Problem; +import core.problem.State; +import core.runner.EngineFeeder; +import core.runner.HeuristicType; +import core.solver.Node; +import core.solver.Searcher; +import core.solver.heuristic.AbstractFrontier; +import core.solver.heuristic.BestFirstSearch; +import core.solver.heuristic.EvaluationType; +import core.solver.heuristic.Predictor; +import xu.solver.heuristic.LinkedFrontier; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; + +/** + * 寻路问题的EngineFeeder + */ +public class FeederXu extends EngineFeeder { + /** + * 从文件输入流中读入NPuzzle问题的实例 + * + * @param io 输入流 + * @return 文件中所有NPuzzle实例 + */ + @Override + public ArrayList getProblems(In io) { + + ArrayList problems = new ArrayList<>(); + //地图的大小 + int size = io.readInt(); + //读入地图 + GridType[][] grids = new GridType[size][]; + for (int i = 0; i < size; i++){ + grids[i] = new GridType[size]; + for (int j = 0; j < size; j++){ + int cellType = io.readInt(); + grids[i][j] = GridType.values()[cellType]; + } + } + while (io.hasNextLine()){ + //读入初始状态 + int row = io.readInt(); + int col = io.readInt(); + Position initialState = new Position(row, col); + //读入目标状态 + row = io.readInt(); + col = io.readInt(); + Position goal = new Position(row, col); + //生成寻路问题的实例,并设置其地图 + PathFinding problem = new PathFinding(initialState, goal, size); + problem.setGrids(grids); + //添加到问题列表 + problems.add(problem); + } + return problems; + } + + @Override + public ArrayList getProblems(Scanner scanner) { + return null; + } + + /** + * 生成采取某种估值机制的Frontier + * + * @param type 结点评估器的类型 + * @return 使用该评估机制的一个Frontier实例 + */ + @Override + public AbstractFrontier getFrontier(EvaluationType type) { + return new LinkedFrontier(Node.evaluator(type)); + } + + /** + * 获得对状态进行估值的Predictor + * + * @param type 估值函数的类型 + * @return 估值函数 + */ + @Override + public Predictor getPredictor(HeuristicType type) { + return Position.predictor(type); + } + + /** + * 生成IdaStar搜索的一个实例 + */ + @Override + public Searcher getIdaStar() { + return null; + } + + /** + * 用来提交头歌评分的Searcher + * + * @return 搜索引擎 + */ + @Override + public Searcher getScoreSearcher() { + return getAStar(HeuristicType.PF_GRID); + } + +} diff --git a/SearchFramework1.0.1/src/xu/problem/pathfinding/GridType.java b/SearchFramework1.0.1/src/xu/problem/pathfinding/GridType.java new file mode 100644 index 0000000..e71409a --- /dev/null +++ b/SearchFramework1.0.1/src/xu/problem/pathfinding/GridType.java @@ -0,0 +1,23 @@ +package xu.problem.pathfinding; + +public enum GridType { + EMPTY('0'), // 空地 + GRASS('#'), // 草地,通过的代价高,普通代价的2倍 + //MUDDY, // 泥地,通过代价为3倍 + WALL('*'); // 石墙,无法通过 + + private final char symbol; + + GridType(char symbol){ + this.symbol = symbol; + } + + public char symbol(){ + return symbol; + } + + @Override + public String toString() { + return symbol + ""; + } +} diff --git a/SearchFramework1.0.1/src/xu/problem/pathfinding/Move.java b/SearchFramework1.0.1/src/xu/problem/pathfinding/Move.java new file mode 100644 index 0000000..14a0054 --- /dev/null +++ b/SearchFramework1.0.1/src/xu/problem/pathfinding/Move.java @@ -0,0 +1,43 @@ +package xu.problem.pathfinding; + +import core.problem.Action; + +public class Move extends Action { + + private final Direction direction; + + public Move(Direction direction) { + this.direction = direction; + } + + public Direction getDirection() { + return direction; + } + + @Override + public void draw() { + System.out.println(toString()); + } + + @Override + public int stepCost() { + return Direction.cost(direction); + } + + @Override + public String toString() { + return direction.symbol() + ""; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + + if (obj instanceof Move) { + Move another = (Move) obj; + //两个Node对象的状态相同,则认为是相同的 + return this.direction.equals(another.direction); + } + return false; + } +} diff --git a/SearchFramework1.0.1/src/xu/problem/pathfinding/PathFinding.java b/SearchFramework1.0.1/src/xu/problem/pathfinding/PathFinding.java new file mode 100644 index 0000000..f6f5c1c --- /dev/null +++ b/SearchFramework1.0.1/src/xu/problem/pathfinding/PathFinding.java @@ -0,0 +1,146 @@ +package xu.problem.pathfinding; + +import core.problem.Action; +import core.problem.Problem; +import core.problem.State; +import core.solver.Node; +import java.util.Deque; + +/** + * 寻路问题 + */ +public class PathFinding extends Problem { + + //地图信息 + GridType[][] grids; + + public PathFinding(State initialState, State goal) { + super(initialState, goal); + } + + public PathFinding(State initialState, State goal, int size) { + super(initialState, goal, size); + grids = new GridType[size][size]; + } + + public GridType[][] getGrids() { + return grids; + } + + public void setGrids(GridType[][] grids) { + for (int i = 0; i < size; i++){ + System.arraycopy(grids[i], 0, this.grids[i], 0, size); + } + } + + /** + * 当前问题是否有解 + * 因为只有通过搜索来判断,所以先默认为true + * @return 有解,true; 无解,false + */ + @Override + public boolean solvable() { + return true; + } + + @Override + public int stepCost(State state, Action action) { + Position position = (Position) state ; + GridType type = grids[position.getRow() - 1][position.getCol() - 1]; + if (type == GridType.EMPTY) + return action.stepCost(); + if (type == GridType.GRASS) + return action.stepCost() * 5; + return Integer.MIN_VALUE; + } + + @Override + protected boolean applicable(State state, Action action) { + int[] offsets = Direction.offset(((Move)action).getDirection()); + int row = ((Position)state).getRow() + offsets[1]; + int col = ((Position)state).getCol() + offsets[0]; + return row > 0 && row <= size && + col > 0 && col <= size && + grids[row - 1][col - 1] != GridType.WALL; + } + + @Override + public void showSolution(Deque path) { + //将地图转换为字符数组 + char[][] grids = new char[size][]; + for (int i = 0; i < size; i++){ + grids[i] = new char[size]; + for (int j = 0; j < size; j++) { + grids[i][j] = this.grids[i][j].symbol(); + } + } + //标记起点 + int row = ((Position)initialState).getRow(); + int col = ((Position)initialState).getCol(); + grids[row - 1][col - 1] = '@'; + //和终点 + row = ((Position)goal).getRow(); + col = ((Position)goal).getCol(); + grids[row - 1][col - 1] = '&'; + + //打印寻路问题。 + System.out.println(initialState + "→" + goal); + //将解路径中的动作符号写入字符数组grids + for (Node node : path) { + Position p = (Position) node.getState(); + Move move = (Move) node.getAction(); + Direction d = move.getDirection(); + grids[p.getRow() - 1][p.getCol() - 1] = d.symbol(); + } + + //打印字符数组 + drawGrid(grids); + } + + private void drawGrid(char[][] grids) { + for (int i = 0; i < size; i++){ + for (int j = 0; j < size; j++) { + System.out.print(grids[i][j] + " "); + } + System.out.println(); + } + } + + /** + * 打印当前问题的起点→终点 + * 和 地图 + */ + @Override + public void draw() { + System.out.println(initialState + "→" + goal); + for (GridType[] rows : grids){ + for (GridType type : rows){ + System.out.print(type.symbol() + " "); + } + System.out.println(); + } + } + + /** + * 打印解路径所采取的动作序列 + * @param path 解路径 + */ + @Override + public void printPath(Deque path) { + if (path == null){ + System.out.println("No Solution."); + return; + } + for (Node node : path) { + Move move = (Move) node.getAction(); + System.out.print(move.getDirection().name() + " "); + } + System.out.println(); + + } + + @Override + public String toString() { + return super.toString(); + } +} diff --git a/SearchFramework1.0.1/src/xu/problem/pathfinding/Point.java b/SearchFramework1.0.1/src/xu/problem/pathfinding/Point.java new file mode 100644 index 0000000..7a3e5e7 --- /dev/null +++ b/SearchFramework1.0.1/src/xu/problem/pathfinding/Point.java @@ -0,0 +1,107 @@ +package xu.problem.pathfinding; + +import java.util.ArrayList; +import java.util.Comparator; + +import static java.util.Comparator.*; + +public class Point implements Comparable{ + + public int getX() { + return x; + } + public void setX(int x) { + this.x = x; + } + public int getY() { + return y; + } + public void setY(int y) { + this.y = y; + } + public Point(int x, int y) { + super(); + this.x = x; + this.y = y; + } + private int x; + private int y; + @Override + public String toString() { + return "(" + x + "," + y + ")"; + } + + public static final Comparator RowColComparator = naturalOrder(); + + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj instanceof Point){ + Point p = (Point) obj; + return this.x == p.x && this.y == p.y; + } + return false; + } + + @Override + public int hashCode() { + return x << 3 | y; + } + + //根据x坐标比较 + public static final Comparator TestComparator = comparingInt(arg0 -> arg0.x); + + //根据到原点的曼哈顿距离进行比较 + public static final Comparator ManhattanComparator = comparingInt(arg0 -> arg0.manhattan(new Point(0, 0))); + + /** + * 当前点对象与参数p之间的曼哈顿距离 + * @param p 另一个点p + * @return 当前点对象与p的曼哈顿距离 + */ + public int manhattan(Point p){ + return Math.abs(this.x - p.x) + Math.abs(this.y - p.y); + } + + /** + * 当前点对象与参数p之间的欧几里得距离,取整 + * @param p 另一个点p + * @return 当前点对象与p的欧几里得距离 + */ + public double euclid(Point p){ + int x = this.x - p.x; + int y = this.y - p.y; + return Math.sqrt(x * x + y * y); + } + + /** + * 自然序,先比较横坐标,再比较纵坐标 + */ + @Override + public int compareTo(Point p) { + if (this.x == p.x) + return this.y - p.y; + + return this.x - p.x; + } + + public static void main(String[] args) { + ArrayList treeset = new ArrayList<>(); + Point p = new Point(3, 5); + treeset.add(p); + p = new Point(4, 5); + treeset.add(p); + p = new Point(2, 7); + treeset.add(p); + p = new Point(3, 7); + treeset.add(p); + p = new Point(3, 1); + treeset.add(p); + treeset.sort(ManhattanComparator); + + for (Point point : treeset) { + System.out.println(point); + } + } +} diff --git a/SearchFramework1.0.1/src/xu/problem/pathfinding/Position.java b/SearchFramework1.0.1/src/xu/problem/pathfinding/Position.java new file mode 100644 index 0000000..244b264 --- /dev/null +++ b/SearchFramework1.0.1/src/xu/problem/pathfinding/Position.java @@ -0,0 +1,132 @@ +package xu.problem.pathfinding; + +import core.problem.Action; +import core.problem.State; +import core.runner.HeuristicType; +import core.solver.Node; +import core.solver.heuristic.Predictor; +import java.util.ArrayList; +import java.util.EnumMap; + +/** + * PathFinding问题的状态 + * 位置状态,表示寻路机器人在什么位置 + */ +public class Position extends State { + public static final int SCALE = 10; //单元格的边长 + public static final double ROOT2 = 1.4; //2的平方根 + + //可移动的方向:四个方向或者八个方向 + private static final int MOVETYPE = 1; //八个方向移动 + private static final Direction[][] directions = new Direction[2][]; + static{ + //四个方向移动 + directions[0] = new Direction[]{Direction.N, Direction.E, Direction.S, Direction.W}; + //八个方向移动 + directions[1] = Direction.values(); + } + + //机器人在场地中的位置 + private final Point point; + + public Position(int row, int col) { + this.point = new Point(row, col); + } + + @Override + public void draw() { + System.out.println(this); + } + + /** + * 当前状态采用action而进入的下一个状态 + * + * @param action 当前状态下,一个可行的action + * @return 下一个状态 + */ + @Override + public State next(Action action) { + //当前Action所带来的位移量 + Direction dir = ((Move)action).getDirection(); + int[] offsets = Direction.offset(dir); + //生成新状态所在的点 + int col = getCol() + offsets[0]; + int row = getRow() + offsets[1]; + + return new Position(row, col); + } + + @Override + public Iterable actions() { + ArrayList moves = new ArrayList<>(); + for (Direction d : directions[MOVETYPE]) + moves.add(new Move(d)); + return moves; + } + + //枚举映射,存放不同类型的启发函数 + private static final EnumMap predictors = new EnumMap<>(HeuristicType.class); + static{ + predictors.put(HeuristicType.PF_EUCLID, + (state, goal) -> ((Position)state).euclid((Position)goal)); + predictors.put(HeuristicType.PF_MANHATTAN, + (state, goal) -> ((Position)state).manhattan((Position)goal)); + predictors.put(HeuristicType.PF_GRID, + (state, goal) -> ((Position)state).gridDistance((Position)goal)); + } + public static Predictor predictor(HeuristicType type){ + return predictors.get(type); + } + + //两个点之间的Grid距离,尽量走对角线 + private int gridDistance(Position goal) { + int width = Math.abs(this.getCol() - goal.getCol()); + int height = Math.abs(this.getRow() - goal.getRow()); + if (width > height) { + return (width - height) * SCALE + height * (int) (SCALE * ROOT2); + } + else{ + return (height - width) * SCALE + width * (int) (SCALE * ROOT2); + } + } + + //两个点之间的曼哈顿距离乘以SCALE + private int manhattan(Position goal) { + return this.point.manhattan(goal.point) * SCALE; + } + + //两个点之间的欧几里德距离 + private int euclid(Position goal) { + return (int) (this.point.euclid(goal.point) * SCALE); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + + if (obj instanceof Position ) { + Position another = (Position) obj; + //两个Node对象的状态相同,则认为是相同的 + return this.point.equals(another.point); + } + return false; + } + + @Override + public int hashCode() { + return point.hashCode(); + } + + @Override + public String toString() { + return point.toString(); + } + + public int getRow() { + return point.getX(); + } + + public int getCol() { + return point.getY(); + } +} diff --git a/SearchFramework1.0.1/src/xu/solver/heuristic/LinkedFrontier.java b/SearchFramework1.0.1/src/xu/solver/heuristic/LinkedFrontier.java new file mode 100644 index 0000000..6079aab --- /dev/null +++ b/SearchFramework1.0.1/src/xu/solver/heuristic/LinkedFrontier.java @@ -0,0 +1,89 @@ +package xu.solver.heuristic; + +import core.problem.State; +import core.solver.Node; +import core.solver.heuristic.AbstractFrontier; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Collection; +/** + * 封装了LinkedList数据结构的Frontier + */ +public class LinkedFrontier extends AbstractFrontier { + //底层实现用的是LinkedList + private final LinkedList nodeList = new LinkedList<>(); + + public LinkedFrontier(Comparator evaluator) { + super(evaluator); + } + + /** + * 获取 Frontier 中,状态为 s 的节点 + * + * @param s 状态 + * @return 存在: 相应的状态为 s 的节点; + * 不存在:null + */ + @Override + protected Node getNode(State s) { + for (Node node: nodeList){ + if (node.getState().equals(s)){ + return node; + } + } + return null; + } + + @Override + public boolean remove(Object o) { + return nodeList.remove(o); + } + + /** + * 将结点node插入到当前有序链表中 + * @param node 要插入的结点 + * @return 插入成功返回true + */ + @Override + public boolean add(Node node) { + int j = 0; + + for (Node value : nodeList) { + if (evaluator.compare(value, node) >= 0) { + break; + } + j++; + } + + nodeList.add(j, node); + + return true; + } + + @Override + public Iterator iterator() { + return nodeList.iterator(); + } + + @Override + public int size() { + return nodeList.size(); + } + + @Override + public boolean offer(Node node) { + return this.add(node); + } + + @Override + public Node poll() { + return nodeList.poll(); + } + + @Override + public Node peek() { + return nodeList.peek(); + } +} diff --git a/SearchFramework1.0.1/test/xu/problem/pathfinding/PathFeederTest.java b/SearchFramework1.0.1/test/xu/problem/pathfinding/PathFeederTest.java new file mode 100644 index 0000000..ca37a20 --- /dev/null +++ b/SearchFramework1.0.1/test/xu/problem/pathfinding/PathFeederTest.java @@ -0,0 +1,29 @@ +package xu.problem.pathfinding; + +import algs4.util.In; +import core.problem.Problem; +import core.runner.EngineFeeder; +import org.junit.jupiter.api.Test; + + + +import java.util.ArrayList; + +class PathFeederTest { + + @Test + void getProblems() { + //生成一个具体的EngineFeeder:FeederXu,引擎饲养员徐老师:) + EngineFeeder feeder = new FeederXu(); + + //从文件中读入问题的实例,NPuzzle问题 + In problemInput = new In("resources/pathfinding.txt"); + //feeder从文件获取所有问题实例 + ArrayList problems = feeder.getProblems(problemInput); + + for (Problem problem : problems){ + problem.draw(); + } + + } +} \ No newline at end of file diff --git a/SearchFramework1.0.1/test/xu/problem/pathfinding/PathFindingTest.java b/SearchFramework1.0.1/test/xu/problem/pathfinding/PathFindingTest.java new file mode 100644 index 0000000..18e57e8 --- /dev/null +++ b/SearchFramework1.0.1/test/xu/problem/pathfinding/PathFindingTest.java @@ -0,0 +1,28 @@ +package xu.problem.pathfinding; + +import algs4.util.In; +import core.problem.Problem; +import core.runner.EngineFeeder; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.*; + +class PathFindingTest { + + @Test + void applicable() { + //生成一个具体的EngineFeeder:FeederXu,引擎饲养员徐老师:) + EngineFeeder feeder = new FeederXu(); + + //从文件中读入问题的实例,NPuzzle问题 + In problemInput = new In("resources/pathfinding.txt"); + //feeder从文件获取所有问题实例 + ArrayList problems = feeder.getProblems(problemInput); + + Position position = new Position(7, 4); + assertFalse(((PathFinding)problems.get(0)).applicable(position, new Move(Direction.S))); + assertTrue(((PathFinding)problems.get(0)).applicable(position, new Move(Direction.E))); + } +} \ No newline at end of file diff --git a/SearchFramework1.0.1/test/xu/problem/pathfinding/PositionTest.java b/SearchFramework1.0.1/test/xu/problem/pathfinding/PositionTest.java new file mode 100644 index 0000000..8eb5411 --- /dev/null +++ b/SearchFramework1.0.1/test/xu/problem/pathfinding/PositionTest.java @@ -0,0 +1,20 @@ +package xu.problem.pathfinding; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PositionTest { + + @Test + void next() { + Position position = new Position(5, 6); + assertEquals(position.next(new Move(Direction.S)), new Position(6, 6)); + + Position next = (Position) position.next(new Move(Direction.E)); // (5,7) + assertEquals(next, new Position(5, 7)); + assertEquals(next.next(new Move(Direction.N)), new Position(4, 7)); + assertEquals(next.next(new Move(Direction.W)), new Position(5, 6)); + + } +} \ No newline at end of file diff --git a/SearchFramework1.0.1/test/xu/solver/heuristic/LinkedFrontierTest.java b/SearchFramework1.0.1/test/xu/solver/heuristic/LinkedFrontierTest.java new file mode 100644 index 0000000..37007dc --- /dev/null +++ b/SearchFramework1.0.1/test/xu/solver/heuristic/LinkedFrontierTest.java @@ -0,0 +1,65 @@ +package xu.solver.heuristic; + +import core.problem.State; +import core.solver.Node; +import core.solver.heuristic.EvaluationType; +import xu.problem.pathfinding.Direction; +import xu.problem.pathfinding.Move; +import xu.problem.pathfinding.Point; +import xu.problem.pathfinding.Position; + +import static org.junit.jupiter.api.Assertions.*; + +class LinkedFrontierTest { + + @org.junit.jupiter.api.Test + void offer() { + LinkedFrontier frontier = new LinkedFrontier(Node.evaluator(EvaluationType.FULL)); + State position = new Position(4, 4); + Node parent = new Node(position, null, null, 0, 15); + + position = new Position(5, 5); + Node node = new Node(position, parent, new Move(Direction.SE), 0, 15); + frontier.offer(node); + + position = new Position(5, 6); + node = new Node(position, node, new Move(Direction.S), 1, 13); + frontier.offer(node); + position = new Position(6, 6); + node = new Node(position, node, new Move(Direction.E), 2, 13); + frontier.offer(node); + position = new Position(7, 6); + node = new Node(position, node, new Move(Direction.E), 3, 9); + frontier.offer(node); + + for (Node node1: frontier){ + System.out.println(node1); + } + System.out.println(); + + position = new Position(9, 6); + node = new Node(position, node, new Move(Direction.E), 2, 13); + + System.out.println(frontier.getNode(node.getState())); + + position = new Position(6, 6); + node = new Node(position, node, new Move(Direction.W), 22, 13); + + System.out.println(frontier.contains(node)); + + System.out.println(); + + position = new Position(5, 6); + node = new Node(position, node, new Move(Direction.S), 3, 10); + frontier.discardOrReplace(node); + + for (Node node1: frontier){ + System.out.println(node1); + } + + System.out.println(); + while (!frontier.isEmpty()){ + frontier.poll().draw(); + } + } +} \ No newline at end of file