main.lib.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package main
  2. /*
  3. #include <string.h>
  4. typedef const char* string_t;
  5. */
  6. import "C"
  7. import (
  8. "os"
  9. "bytes"
  10. "unsafe"
  11. "reflect"
  12. "runtime"
  13. "os/exec"
  14. "archive/zip"
  15. "path/filepath"
  16. "kumachan/standalone/qt"
  17. "kumachan/standalone/util/fatal"
  18. "kumachan/interpreter"
  19. "kumachan/interpreter/compiler"
  20. )
  21. var coproc *os.Process
  22. //export StartCoproc
  23. func StartCoproc(interpreter_cmd_ C.string_t, file_rel_path C.string_t, argc C.int, argv *C.string_t) {
  24. var interpreter_cmd = getString(interpreter_cmd_)
  25. var file = getAbsPath(getString(file_rel_path))
  26. var args = getStrings(argc, argv)
  27. if interpreter_cmd != "" {
  28. args = append([] string { file }, args...)
  29. file = interpreter_cmd
  30. }
  31. var a_out, a_in, err = os.Pipe()
  32. if err != nil { fatal.ThrowError(err) }
  33. { var b_out, b_in, err = os.Pipe()
  34. if err != nil { fatal.ThrowError(err) }
  35. os.Stdin = a_out
  36. os.Stdout = b_in
  37. var cmd = exec.Command(file, args...)
  38. cmd.Stdin = b_out
  39. cmd.Stdout = a_in
  40. cmd.Stderr = os.Stderr
  41. { var err = cmd.Start()
  42. if err != nil { fatal.ThrowError(err) }
  43. coproc = cmd.Process }}
  44. }
  45. //export CompileAndRun
  46. func CompileAndRun(archive_addr *C.char, archive_size C.size_t, file_name C.string_t, entry_ns C.string_t) {
  47. runtime.LockOSThread()
  48. var archive = getBytes(archive_addr, archive_size)
  49. var r, err = zip.NewReader(bytes.NewReader(archive), int64(len(archive)))
  50. if err != nil { fatal.ThrowError(err) }
  51. var fs = compiler.ZipFilesystem { Id: "default", Reader: r }
  52. var file = getString(file_name)
  53. { var p, _, err = interpreter.Compile(file, fs)
  54. if err != nil { fatal.ThrowError(err) }
  55. var args = make([] string, len(os.Args))
  56. copy(args, os.Args)
  57. if len(args) > 0 {
  58. args = args[1:]
  59. }
  60. var p_ns = getString(entry_ns)
  61. var p_args = args
  62. qt.Init()
  63. { var err = interpreter.Run(p, p_ns, p_args, nil, func() { qt.Exit(0) })
  64. if err != nil { fatal.ThrowError(err) }
  65. qt.Main() }}
  66. }
  67. func getBytes(ptr *C.char, size C.size_t) ([] byte) {
  68. var h = &reflect.SliceHeader {
  69. Data: uintptr(unsafe.Pointer(ptr)),
  70. Len: int(size),
  71. Cap: int(size),
  72. }
  73. return *(*([] byte))(unsafe.Pointer(h))
  74. }
  75. func getString(raw C.string_t) string {
  76. var h = &reflect.StringHeader {
  77. Data: uintptr(unsafe.Pointer(raw)),
  78. Len: int(C.strlen(raw)),
  79. }
  80. return *(*string)(unsafe.Pointer(h))
  81. }
  82. func getStrings(n C.int, ptr *C.string_t) ([] string) {
  83. var h = &reflect.SliceHeader {
  84. Data: uintptr(unsafe.Pointer(ptr)),
  85. Len: int(n),
  86. Cap: int(n),
  87. }
  88. var t = *(*([] C.string_t))(unsafe.Pointer(h))
  89. var all = make([] string, len(t))
  90. for i := range t {
  91. all[i] = getString(t[i])
  92. }
  93. return all
  94. }
  95. func getAbsPath(rel_path string) string {
  96. var exe_file, err = os.Executable()
  97. if err != nil { fatal.ThrowError(err) }
  98. var exe_dir = filepath.Dir(exe_file)
  99. return filepath.Join(exe_dir, rel_path)
  100. }
  101. // dummy, needed by Go compiler
  102. func main() {}