script-compiler.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <sys/types.h>
  4. #include <sys/wait.h>
  5. #include <unistd.h>
  6. #include "Crown.h"
  7. using namespace crown;
  8. const char* command = NULL;
  9. const char* option = NULL;
  10. const char* root_path = NULL;
  11. const char* resource_in = NULL;
  12. const char* resource_out = NULL;
  13. void parse_command_line(int argc, char** argv);
  14. void print_help_message(const char* program_name);
  15. void compile_script(char* tmp_out);
  16. /// Lua scripts compiler
  17. int main(int argc, char** argv)
  18. {
  19. parse_command_line(argc, argv);
  20. // FIXME: validate input
  21. Filesystem fs_root(root_path);
  22. if (!fs_root.exists(resource_in))
  23. {
  24. printf("%s: ERROR: %s does not exist. Aborting.\n", argv[0], resource_in);
  25. return -1;
  26. }
  27. char resource_basename[256];
  28. char resource_extension[256];
  29. path::filename_without_extension(resource_in, resource_basename, 256);
  30. path::extension(resource_in, resource_extension, 256);
  31. uint32_t resource_basename_hash = hash::fnv1a_32(resource_basename, string::strlen(resource_basename));
  32. uint32_t resource_extension_hash = hash::fnv1a_32(resource_extension, string::strlen(resource_extension));
  33. char tmp_file[256];
  34. compile_script(tmp_file);
  35. FileStream* src_file = (FileStream*)fs_root.open(tmp_file, SOM_READ);
  36. size_t src_file_size = src_file->size();
  37. ArchiveEntry archive_entry;
  38. archive_entry.name = resource_basename_hash;
  39. archive_entry.type = resource_extension_hash;
  40. archive_entry.offset = sizeof (ArchiveEntry);
  41. archive_entry.size = src_file_size + sizeof(uint32_t);
  42. void* buffer = new uint8_t[src_file_size];
  43. src_file->read(buffer, src_file_size);
  44. fs_root.close(src_file);
  45. FileStream* dest_file = (FileStream*)fs_root.open(resource_out, SOM_WRITE);
  46. dest_file->write(&archive_entry, sizeof(ArchiveEntry));
  47. dest_file->write(&src_file_size, sizeof(uint32_t));
  48. dest_file->write(buffer, src_file_size);
  49. fs_root.close(dest_file);
  50. return 0;
  51. }
  52. void parse_command_line(int argc, char** argv)
  53. {
  54. // Parse arguments
  55. ArgsOption options[] =
  56. {
  57. "help", AOA_NO_ARGUMENT, NULL, 'h',
  58. "root-path", AOA_REQUIRED_ARGUMENT, NULL, 'r',
  59. "resource-in", AOA_REQUIRED_ARGUMENT, NULL, 'i',
  60. "resource-out", AOA_REQUIRED_ARGUMENT, NULL, 'o',
  61. NULL, 0, NULL, 0
  62. };
  63. Args args(argc, argv, "", options);
  64. while (1)
  65. {
  66. int32_t ret = args.next_option();
  67. switch (ret)
  68. {
  69. case -1:
  70. {
  71. return;
  72. }
  73. // Help message
  74. case 'h':
  75. {
  76. print_help_message(argv[0]);
  77. exit(0);
  78. }
  79. // Root path
  80. case 'r':
  81. {
  82. if (args.option_argument() == NULL)
  83. {
  84. printf("%s: ERROR: missing path after `--root-path`\n", argv[0]);
  85. exit(-1);
  86. }
  87. root_path = args.option_argument();
  88. break;
  89. }
  90. // Resource in
  91. case 'i':
  92. {
  93. if (args.option_argument() == NULL)
  94. {
  95. printf("%s: ERROR: missing path after `--resource-in`\n", argv[0]);
  96. exit(-1);
  97. }
  98. resource_in = args.option_argument();
  99. break;
  100. }
  101. // Resource out
  102. case 'o':
  103. {
  104. if (args.option_argument() == NULL)
  105. {
  106. printf("%s: ERROR: missing path after `--resource-out`\n", argv[0]);
  107. exit(-1);
  108. }
  109. resource_out = args.option_argument();
  110. break;
  111. }
  112. default:
  113. {
  114. break;
  115. }
  116. }
  117. }
  118. }
  119. void print_help_message(const char* program_name)
  120. {
  121. printf("Usage: %s [options]\n", program_name);
  122. printf("Options:\n\n");
  123. printf(" --help Show this help.\n");
  124. printf(" --root-path <path> The _absolute_ <path> whether to look for the input resource.\n");
  125. printf(" --resource-in <path> The _relative_ <path> of the input resource.\n");
  126. printf(" --resource-out <width> The _relative_ <path> of the output resource.\n");
  127. }
  128. void compile_script(char* tmp_out)
  129. {
  130. char* command = "luajit";
  131. char* option = "-bl";
  132. size_t in_len = strlen(root_path) + strlen(resource_in);
  133. char in[256];
  134. strcpy(in, root_path);
  135. strcat(in, resource_in);
  136. char rel_out[256];
  137. strncpy(rel_out, resource_in, strlen(resource_in) - 3);
  138. strcat(rel_out, "tmp");
  139. char out[256];
  140. strcpy(out, root_path);
  141. strcat(out, rel_out);
  142. strcpy(tmp_out, rel_out);
  143. // Fork for exec
  144. pid_t child = 0;
  145. child = fork();
  146. if (child < 0)
  147. {
  148. printf("Failed fork during compile_script() call.");
  149. return;
  150. }
  151. if (child == 0)
  152. {
  153. wait(NULL);
  154. }
  155. else
  156. {
  157. execl("/usr/local/bin/luajit", command, option, in, out, NULL);
  158. }
  159. }