Last active
August 5, 2024 01:17
-
-
Save duangsuse/50937b30cbf24a6be0eb69da3a7231b3 to your computer and use it in GitHub Desktop.
Developing: tool to cache java main() statics e.g. $ kotlinc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env bash | |
#kotlinc -include-runtime catdo.kt -d ~/catdo.jar; install -Dm755 -t ~ catdo | |
catdo() { local k=$1;set -- "$PWD0" "${@:2}"; printf "%s\0" "$@" >buf; printf "%08x" $(wc -c <buf)|basenc --base16 -d >>$k; cat buf>>$k | |
ruby -e 'k,bf=ARGV; while File.read(bf)!=k do end' $k buf; cat $k | |
} | |
[ -z $2 ] &&env JAVACMD=$PWD/catdo $1 &&exit | |
j=$(echo "$@"|sed -E 's/(\S*Main)/CatdoKt \1/;s/-cp /\0catdo.jar:/') | |
read f fl <<<$(sed -E 's/.* (\S*Main)(.*)/\1.text \2/'<<<$j) | |
PWD0="$PWD" | |
cd | |
if [ -f "$f" ]; then | |
echo VM .: jstack $(lsof -t $f) | |
catdo "$f" $fl;exit | |
fi | |
echo $j | |
nohup java -Djava.security.manager=allow $j 2>&1|tail -n+6 & # :3 "terminally deprecated"?? won't fix System::exit AOP? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.* | |
typealias Bytes=ByteArray //..n:i32 i8*n | |
typealias Pipe<T> =(T)->T | |
object SystemExit: Error("Re-compute static{}? no way!") | |
var osExit=0 | |
val out=System.out.also { // ??? https://openjdk.org/jeps/411#:~:text=Blocking%20System::exit%20—%20Some | |
// 😅Python😅 fixed this(no finally{} when exit()) in design by raise SystemExit | |
// and even CPython+pip is faster than .main.kts (btw wtf is ".main"?) | |
System.setSecurityManager(object: SecurityManager() { | |
override fun checkExit(i:Int){osExit=i;throw SystemExit} | |
override fun checkPermission(p:java.security.Permission){ | |
if(p.name=="setIO"&&res._v==null)ps.tee() | |
} | |
}) | |
} | |
var ps:PrintStream=out | |
val jvm=Runtime.getRuntime() | |
val uBuf=File("buf") | |
fun PrintStream.tee(){res(1); System.setOut(this);System.setErr(this); res.v<Int>()} | |
@JvmStatic fun main(vararg cli:String) = bind(File("${cli[0]}.text").apply{deleteOnExit()}) { | |
//return String(it).reversed().toByteArray() | |
val argv=it.sep { A,B-> if(B == 0.toByte())1 else -1 }.map { String(it) } | |
val arg=argv.slice(1..<argv.size).map { listOf("c","").find{c->val u=File(argv[0],it+c); res(if(u.isFile) "$u" else null)}; res.v<String>() ?: it } | |
var r=""; var mm=0L | |
//ProcessBuilder(arg).run{start(); waitFor()} | |
out.print(arg); val ms=measureTime { mm=varDiff{-jvm.freeMemory()}.invoke { | |
ByteArrayOutputStream().use { | |
ps=PrintStream(it); ps.tee() | |
r=try { | |
unifyErr{ Class.forName(cli[0]).getDeclaredMethod("main", Array<String>::class.java)(null, arg.toTypedArray()) } | |
"$it" } | |
catch (e: ClassNotFoundException) {".${cli[0]} NoDef"} | |
catch (e: NoSuchMethodException) {"${cli[0]} has no main()"} | |
catch (_: SystemExit) {"$it\n-- $osExit --\n"} | |
catch (e: Exception) {".${e} e"} | |
out.print(" ${r.count { it == '\n' } + 1}L ${r.length}c") | |
} | |
}} | |
out.println(" ${ms/1000.0}s ${mm/1024/1024}M") | |
if(osExit==2)r+="☕️ Simply Ctlr+Shift +Tab for REPLs, or .: rePTYr $(pidof java)\n" | |
r.toByteArray() | |
} | |
fun unifyErr(f:()->Unit)=try{f()}catch(e:Throwable){ var ex=e | |
while((ex as? java.lang.reflect.InvocationTargetException)!=null) ex=ex.cause!! | |
throw ex | |
} | |
val measureTime=varDiff{System.currentTimeMillis()} | |
fun varDiff(v: () -> Long)=fun(f:()->Unit)=run { | |
val v0 = v(); f(); v() - v0 | |
} | |
fun bind(u:File,f:Pipe<Bytes>) = RandomAccessFile(u, "rw").run { | |
channel.force(true) | |
setLength(0);var n=0 | |
while (true) { | |
while(length().toInt()==n){} | |
n=readInt(); val ln=Bytes(n); while(read(ln)!=n){} | |
seek(0); write(f(ln).also{n=it.size}) | |
setLength(n.toLong()); uBuf.writeText(u.name) //just accept(1) + onDiskBuffer | |
} | |
} /* | |
echo=lambda x:x[::-1] | |
def bind(f, u=open("a.txt",'wb+')): | |
while True: | |
while (ln:=u.read())==b'': pass # see also for fd,ev in select.poll(): | |
u.seek(0); u.truncate(0) | |
u.write(f(ln)); u.flush() #echo >> | |
bind(echo) */ | |
fun ByteArray.sep(skip: (Byte, Byte) -> Int) = mutableListOf<ByteArray>().also { | |
var i0 = 0; var d=0 | |
for (i in indices) if(i>0&& skip(this[i - 1], this[i]).also{d=it}!=-1) { | |
it.add(sliceArray(i0 until i)); i0 = i+d | |
} | |
if (i0 < size) { | |
it.add(sliceArray(i0 until size)) | |
} | |
} | |
object res { | |
var _v=null as Any? | |
operator fun invoke(v:Any?)=v?.let{_v=it; true} ?: false | |
fun<T> v()= _v?.let{_v=null;it as T} | |
} | |
//4 early bug: | |
// sep{} don't skip \0 byte, File.exist always false | |
// mistaken invoke(vararg Str is Str[]); -cp no multiple | |
// exit()&print*() is not handled | |
// InvocationTargetException(SystemExit) is error | |
// #BUG while [ "$k" != "$(cat buf)" ]; do false; done; cat $k | |
//TODO | |
// /buf race condition | |
// sendfile/* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.file.*; | |
import java.util.*; | |
import java.util.function.* | |
void main() { | |
watch(mk(c->{ | |
c.put("a.txt", () -> System.out.println("File modified")); | |
})); | |
} | |
<R> R dd(R x){System.err.println(x);return x;} | |
<K,V>Map<K,V> mk(Consumer<Map<K,V>> f) { var r=new HashMap<K,V>(); f.accept(r); return r;} | |
void newPoll(Runnable f) { | |
new Thread(() -> { while (true) { | |
f.run(); | |
}}).start(); | |
} | |
void watch(Map<String, Runnable> c) {try { | |
var wa = FileSystems.getDefault().newWatchService(); | |
for(var u:c.keySet()) dd(Paths.get( new File(u).getCanonicalFile().getParent())).register(wa, StandardWatchEventKinds.ENTRY_MODIFY); | |
newPoll(()->{ | |
WatchKey key; | |
try{key = wa.take();}catch(Exception e){dd(0);return;} | |
for (WatchEvent<?> event : key.pollEvents()) { | |
var f=c.get(dd(((Path) event.context()).toString())); | |
if(f!=null)f.run(); | |
} | |
key.reset(); | |
});} catch (Exception e) {} | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment