sqmix.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "squirrel.h"
  2. #include "sqstdblobimpl.h"
  3. #define MixInteger SQInteger
  4. #include "code_mix_prep.c"
  5. /* Generic loader function. Load the data found in the state in the lua engine
  6. */
  7. static SQRESULT mix_loadbuffer(HSQUIRRELVM sqvm, mix_state_t *S, const SQChar *name) {
  8. SQRESULT res;
  9. S->pos = 0;
  10. if (S->size > 0 && S->buffer[0] == '#') {
  11. while (S->pos < S->size && S->buffer[S->pos] != '\n')
  12. ++S->pos;
  13. ++S->pos;
  14. S->token = tok_sh;
  15. } else {
  16. S->token = tok_code_end;
  17. }
  18. S->error = NULL;
  19. res = sq_compile(sqvm, sq_mix_reader_char, S, name, SQTrue);
  20. if (S->error != NULL) {
  21. return sq_throwerror(sqvm, S->error);
  22. } else if (res != 0) {
  23. sq_pushnull(sqvm);
  24. //lua_insert(sqvm, -2);
  25. return 2;
  26. }
  27. return 1;
  28. }
  29. SQ_OPT_STRING_STRLEN();
  30. /* Read the options common to mix_loadbuffer and mix_loadfile and store them in
  31. * the state.
  32. */
  33. static SQRESULT mix_stateopt(HSQUIRRELVM sqvm, mix_state_t *S) {
  34. SQ_FUNC_VARS(sqvm);
  35. SQ_OPT_STRING(sqvm, 3, code_start, "{%");
  36. S->code_start = code_start;
  37. S->code_startsize = code_start_size;
  38. if (S->code_startsize == 0)
  39. return sq_throwerror(sqvm, _SC("code_start separator cannot be empty"));
  40. SQ_OPT_STRING(sqvm, 4, code_end, "%}");
  41. S->code_end = code_end;
  42. S->code_endsize = code_end_size;
  43. if (S->code_endsize == 0)
  44. return sq_throwerror(sqvm, _SC("code_end separator cannot be empty"));
  45. SQ_OPT_STRING(sqvm, 5, expr_code, "=");
  46. S->expr = expr_code;
  47. S->exprsize = expr_code_size;
  48. if (S->exprsize == 0)
  49. return sq_throwerror(sqvm, _SC("expr separator cannot be empty"));
  50. SQ_OPT_STRING(sqvm, 6, print_code, "mix_write");
  51. if (print_code_size == 0)
  52. return sq_throwerror(sqvm, _SC("mix_write function name cannot be empty"));
  53. snprintf(S->print_out, sizeof(S->print_out), "%s(\"", print_code);
  54. S->print_outsize = strlen(S->print_out);
  55. S->result_size = 0;
  56. return 0;
  57. }
  58. static SQRESULT mix_loadfile(HSQUIRRELVM sqvm) {
  59. const SQChar *filename;
  60. FILE *file;
  61. mix_state_t S;
  62. sq_mix_init(&S, 0, 0, 0,0,0,0);
  63. sq_getstring(sqvm, 2, &filename);
  64. SQRESULT rc = mix_stateopt(sqvm, &S);
  65. if(rc) return rc;
  66. file = fopen(filename, _SC("r"));
  67. if (file == NULL) {
  68. return sq_throwerror(sqvm, _SC("cannot open file <%s>"), filename);
  69. }
  70. fseek(file, 0, SEEK_END);
  71. S.size = ftell(file);
  72. fseek(file, 0, SEEK_SET);
  73. SQBlob buffer(0, S.size);
  74. if (fread(buffer.GetBuf(), S.size, 1, file) != 1) {
  75. fclose(file);
  76. return sq_throwerror(sqvm, _SC("cannot read file <%s>"), filename);
  77. }
  78. S.buffer = (const char*)buffer.GetBuf();
  79. fclose(file);
  80. return mix_loadbuffer(sqvm, &S, filename);
  81. }
  82. static SQRESULT mix_loadstring(HSQUIRRELVM sqvm) {
  83. mix_state_t S;
  84. sq_mix_init(&S, 0, 0, 0,0,0,0);
  85. sq_getstring(sqvm, 2, &S.buffer);
  86. S.size = sq_getsize(sqvm, 2);
  87. mix_stateopt(sqvm, &S);
  88. return mix_loadbuffer(sqvm, &S, "chunk");
  89. }
  90. const SQChar validate_format_mask[] = _SC(".s s|o s|o s|o s");
  91. #define _DECL_MIX_FUNC(name,nparams,pmask) {_SC(#name), mix_##name,nparams,pmask}
  92. static SQRegFunction mix_obj_funcs[]={
  93. _DECL_MIX_FUNC(loadfile,-2,validate_format_mask),
  94. _DECL_MIX_FUNC(loadstring,-2,validate_format_mask),
  95. {0,0}
  96. };
  97. #undef _DECL_MIX_FUNC
  98. #ifdef __cplusplus
  99. extern "C" {
  100. #endif
  101. /* This defines a function that opens up your library. */
  102. SQRESULT sq_register_mix (HSQUIRRELVM sqvm) {
  103. //add a namespace sqmix
  104. sq_pushstring(sqvm,_SC("sqmix"),-1);
  105. sq_newclass(sqvm,SQFalse);
  106. sq_insert_reg_funcs(sqvm, mix_obj_funcs);
  107. sq_newslot(sqvm,-3,SQTrue); //add sqmix table to the root table
  108. return SQ_OK;
  109. }
  110. #ifdef __cplusplus
  111. }
  112. #endif