main.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5. #include "quickjs.h"
  6. #include "quickjs-libc.h"
  7. #ifdef _WIN32
  8. #include <Windows.h>
  9. #include <direct.h>
  10. static JSValue js_os_exec_win(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  11. JSValue args = argv[0];
  12. JSValue val = JS_GetPropertyStr(ctx, args, "length");
  13. uint32_t exec_argc;
  14. JS_ToUint32(ctx, &exec_argc, val);
  15. char **exec_argv = js_mallocz(ctx, sizeof(exec_argv[0]) * (exec_argc + 1));
  16. for(int i = 0; i < exec_argc; i++) {
  17. val = JS_GetPropertyUint32(ctx, args, i);
  18. exec_argv[i] = JS_ToCString(ctx, val);
  19. JS_FreeValue(ctx, val);
  20. }
  21. exec_argv[exec_argc] = NULL;
  22. if (argc >= 2) {
  23. JSValue options = argv[1];
  24. val = JS_GetPropertyStr(ctx, options, "cwd");
  25. if (!JS_IsUndefined(val)) {
  26. char *cwd = JS_ToCString(ctx, val);
  27. JS_FreeValue(ctx, val);
  28. _chdir(cwd);
  29. }
  30. }
  31. char cmd[1024];
  32. cmd[0] = 0;
  33. for (int i = 0; i < exec_argc; ++i) {
  34. strcat(cmd, exec_argv[i]);
  35. strcat(cmd, " ");
  36. }
  37. HANDLE hReadPipe, hWritePipe;
  38. SECURITY_ATTRIBUTES saAttr;
  39. saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
  40. saAttr.bInheritHandle = TRUE;
  41. saAttr.lpSecurityDescriptor = NULL;
  42. CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0);
  43. SetHandleInformation(hReadPipe, HANDLE_FLAG_INHERIT, 0);
  44. STARTUPINFO si;
  45. PROCESS_INFORMATION pi;
  46. ZeroMemory(&si, sizeof(si));
  47. si.cb = sizeof(si);
  48. si.dwFlags = STARTF_USESTDHANDLES;
  49. si.hStdOutput = hWritePipe;
  50. si.hStdError = hWritePipe;
  51. ZeroMemory(&pi, sizeof(pi));
  52. CreateProcessA(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
  53. CloseHandle(hWritePipe);
  54. char buf[4096];
  55. int buf_len = 0;
  56. int bytes_read;
  57. while (ReadFile(hReadPipe, buf + buf_len, 4096 - buf_len - 1, &bytes_read, NULL) && bytes_read > 0) {
  58. buf_len += bytes_read;
  59. if (buf_len >= 4096 - 1) {
  60. break;
  61. }
  62. }
  63. buf[buf_len] = '\0';
  64. CloseHandle(hReadPipe);
  65. WaitForSingleObject(pi.hProcess, INFINITE);
  66. DWORD exit_code;
  67. GetExitCodeProcess(pi.hProcess, &exit_code);
  68. CloseHandle(pi.hProcess);
  69. CloseHandle(pi.hThread);
  70. printf("%s", buf);
  71. JSValue result = JS_NewObject(ctx);
  72. JS_SetPropertyStr(ctx, result, "stdout", JS_NewString(ctx, buf));
  73. JS_SetPropertyStr(ctx, result, "status", JS_NewInt32(ctx, (int32_t)exit_code));
  74. return result;
  75. }
  76. #endif
  77. void alang(char *source, char *output);
  78. static JSValue js_alang(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  79. const char *source = JS_ToCString(ctx, argv[0]);
  80. const char *output = JS_ToCString(ctx, argv[1]);
  81. alang(source, output);
  82. return JS_UNDEFINED;
  83. }
  84. int ashader(char *shader_lang, char *from, char *to);
  85. static JSValue js_ashader(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  86. const char *shader_lang = JS_ToCString(ctx, argv[0]);
  87. const char *from = JS_ToCString(ctx, argv[1]);
  88. const char *to = JS_ToCString(ctx, argv[2]);
  89. ashader(shader_lang, from, to);
  90. return JS_UNDEFINED;
  91. }
  92. void export_k(const char *from, const char *to);
  93. JSValue js_export_k(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  94. const char *from = JS_ToCString(ctx, argv[0]);
  95. const char *to = JS_ToCString(ctx, argv[1]);
  96. export_k(from, to);
  97. return JS_UNDEFINED;
  98. }
  99. void export_ico(const char *from, const char *to);
  100. JSValue js_export_ico(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  101. const char *from = JS_ToCString(ctx, argv[0]);
  102. const char *to = JS_ToCString(ctx, argv[1]);
  103. export_ico(from, to);
  104. return JS_UNDEFINED;
  105. }
  106. void export_png(const char *from, const char *to, int width, int height);
  107. JSValue js_export_png(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
  108. const char *from = JS_ToCString(ctx, argv[0]);
  109. const char *to = JS_ToCString(ctx, argv[1]);
  110. int32_t width;
  111. JS_ToInt32(ctx, &width, argv[2]);
  112. int32_t height;
  113. JS_ToInt32(ctx, &height, argv[3]);
  114. export_png(from, to, width, height);
  115. return JS_UNDEFINED;
  116. }
  117. int main(int argc, char **argv) {
  118. FILE *fp = fopen(argv[1], "rb");
  119. fseek(fp , 0, SEEK_END);
  120. int size = ftell(fp);
  121. rewind(fp);
  122. char *buffer = malloc(size + 1);
  123. buffer[size] = 0;
  124. fread(buffer, size, 1, fp);
  125. fclose(fp);
  126. JSRuntime *runtime = JS_NewRuntime();
  127. JSContext *ctx = JS_NewContext(runtime);
  128. js_std_init_handlers(runtime);
  129. js_std_add_helpers(ctx, argc, argv);
  130. js_init_module_std(ctx, "std");
  131. js_init_module_os(ctx, "os");
  132. JSValue global_obj = JS_GetGlobalObject(ctx);
  133. JSValue amake = JS_NewObject(ctx);
  134. JS_SetPropertyStr(ctx, amake, "export_k", JS_NewCFunction(ctx, js_export_k, "export_k", 2));
  135. JS_SetPropertyStr(ctx, amake, "export_ico", JS_NewCFunction(ctx, js_export_ico, "export_ico", 2));
  136. JS_SetPropertyStr(ctx, amake, "export_png", JS_NewCFunction(ctx, js_export_png, "export_png", 4));
  137. #ifdef _WIN32
  138. JS_SetPropertyStr(ctx, amake, "os_exec_win", JS_NewCFunction(ctx, js_os_exec_win, "os_exec_win", 1));
  139. #endif
  140. JS_SetPropertyStr(ctx, amake, "alang", JS_NewCFunction(ctx, js_alang, "alang", 2));
  141. JS_SetPropertyStr(ctx, amake, "ashader", JS_NewCFunction(ctx, js_ashader, "ashader", 3));
  142. JS_SetPropertyStr(ctx, global_obj, "amake", amake);
  143. JS_FreeValue(ctx, global_obj);
  144. JSValue ret = JS_Eval(ctx, buffer, size, "make.js", JS_EVAL_TYPE_MODULE);
  145. if (JS_IsException(ret)) {
  146. js_std_dump_error(ctx);
  147. JS_ResetUncatchableError(ctx);
  148. }
  149. JS_RunGC(runtime);
  150. free(buffer);
  151. return 0;
  152. }