1
1
package io .kaitai .struct
2
2
3
3
import java .io .{File , FileWriter }
4
+ import java .net .URLDecoder
4
5
5
6
import io .kaitai .struct .CompileLog ._
6
7
import io .kaitai .struct .JavaMain .CLIConfig
@@ -111,14 +112,79 @@ object JavaMain {
111
112
parser.parse(args, CLIConfig ())
112
113
}
113
114
115
+ /**
116
+ * Insanely hacky method that relies on some JVM black magic to get
117
+ * application "home". From that, we can check if it has a "formats" subdir,
118
+ * and if it does, consider that an additional default ksy imports path.
119
+ * @return additional import search path ("default", platform-specific one),
120
+ * if it's found
121
+ */
122
+ private def homePath : Option [String ] = {
123
+ // fStr is mysterious and probably unreliable, but that's the best I've
124
+ // came up with. It uses java.security API, in which CodeSource is used
125
+ // to have indicative "code location", but AFAIK, in Sun/Oracle applications
126
+ // it is only used as URL for comparison purposes. It is URL-encoded, so
127
+ // we need to decode it as well.
128
+ //
129
+ // Linux, from IDE:
130
+ // $HOME/git/kaitai_struct/compiler/jvm/target/scala-2.11/classes/
131
+ //
132
+ // Linux, from stage:
133
+ // $HOME/git/kaitai_struct/compiler/jvm/target/universal/stage/lib/io.kaitai.kaitai-struct-compiler-0.7-SNAPSHOT.jar
134
+ //
135
+ // Linux, from "sbt compilerJVM/run"
136
+ // $HOME/git/kaitai_struct/compiler/jvm/target/scala-2.11/classes/
137
+ //
138
+ // Linux, from universal, custom install path:
139
+ // /tmp/a%20b/kaitai-struct-compiler-0.7-SNAPSHOT/lib/io.kaitai.kaitai-struct-compiler-0.7-SNAPSHOT.jar
140
+ //
141
+ // Linux, from Debian install:
142
+ // /usr/share/kaitai-struct-compiler/lib/io.kaitai.kaitai-struct-compiler-0.7-SNAPSHOT.jar
143
+ //
144
+ // Windows, default install path:
145
+ // /C:/Program%20Files/kaitai-struct-compiler/lib/io.kaitai.kaitai-struct-compiler-0.7-SNAPSHOT.jar
146
+ //
147
+ // Windows, custom install path with spaces and non-latin chars:
148
+ // /G:/%d0%b3%d0%b4%d0%b5-%d1%82%d0%be%20%d1%82%d0%b0%d0%bc/lib/io.kaitai.kaitai-struct-compiler-0.7-SNAPSHOT.jar
149
+
150
+ val fStr = classOf [JavaMain ].getProtectionDomain.getCodeSource.getLocation.getPath
151
+ Log .importOps.info(() => s " home path: location = $fStr" )
152
+
153
+ if (fStr.endsWith(" .jar" )) {
154
+ val fDec = URLDecoder .decode(fStr, " UTF-8" )
155
+ Log .importOps.info(() => s " ... URL-decoded = $fDec" )
156
+
157
+ val homeFile = new File (fDec).getParentFile.getParentFile
158
+ Log .importOps.info(() => s " ... home = $homeFile" )
159
+
160
+ if (homeFile.exists) {
161
+ val homeFormat = new File (homeFile, " formats" )
162
+ Log .importOps.info(() => s " ... formats = $homeFormat" )
163
+ if (homeFormat.exists) {
164
+ Some (homeFormat.toString)
165
+ } else {
166
+ Log .importOps.info(() => " ... home formats dir doesn't exist => fail" )
167
+ None
168
+ }
169
+ } else {
170
+ Log .importOps.info(() => s " ... home doesn't exist => no home import paths " )
171
+ None
172
+ }
173
+ } else {
174
+ Log .importOps.info(() => s " ... not a jar, we're not running a packaged app => no home " )
175
+ None
176
+ }
177
+ }
178
+
114
179
private def envPaths : List [String ] =
115
180
sys.env.get(" KSPATH" ).toList.flatMap((x) => x.split(File .pathSeparatorChar))
116
181
117
182
def main (args : Array [String ]): Unit = {
118
183
parseCommandLine(args) match {
119
184
case None => System .exit(1 )
120
185
case Some (config0) =>
121
- val config = config0.copy(importPaths = config0.importPaths ++ envPaths)
186
+ Log .initFromVerboseFlag(config0.verbose)
187
+ val config = config0.copy(importPaths = config0.importPaths ++ envPaths ++ homePath)
122
188
new JavaMain (config).run()
123
189
}
124
190
}
@@ -127,8 +193,6 @@ object JavaMain {
127
193
class JavaMain (config : CLIConfig ) {
128
194
import JavaMain ._
129
195
130
- Log .initFromVerboseFlag(config.verbose)
131
-
132
196
def run (): Unit = {
133
197
val logs : Map [String , InputEntry ] = config.srcFiles.map { srcFile =>
134
198
val log = if (config.throwExceptions) {
0 commit comments