sqstdaux.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* see copyright notice in squirrel.h */
  2. #include <squirrel.h>
  3. #include <sqstdaux.h>
  4. #include <stdio.h>
  5. #include <assert.h>
  6. #include <stdarg.h>
  7. void sqstd_printcallstack(HSQUIRRELVM v)
  8. {
  9. SQPRINTFUNCTION pf = sq_geterrorfunc(v);
  10. if(pf) {
  11. SQStackInfos si;
  12. SQInteger i;
  13. SQFloat f;
  14. const SQChar *s;
  15. SQInteger level=1; //1 is to skip this function that is level 0
  16. const SQChar *name=0;
  17. SQInteger seq=0;
  18. pf(v,_SC("\nCALLSTACK\n"));
  19. while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
  20. {
  21. const SQChar *fn=_SC("unknown");
  22. const SQChar *src=_SC("unknown");
  23. if(si.funcname)fn=si.funcname;
  24. if(si.source)src=si.source;
  25. pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line);
  26. level++;
  27. }
  28. level=0;
  29. pf(v,_SC("\nLOCALS\n"));
  30. for(level=0;level<10;level++){
  31. seq=0;
  32. while((name = sq_getlocal(v,level,seq)))
  33. {
  34. seq++;
  35. switch(sq_gettype(v,-1))
  36. {
  37. case OT_NULL:
  38. pf(v,_SC("[%s] NULL\n"),name);
  39. break;
  40. case OT_INTEGER:
  41. sq_getinteger(v,-1,&i);
  42. pf(v,_SC("[%s] %d\n"),name,i);
  43. break;
  44. case OT_FLOAT:
  45. sq_getfloat(v,-1,&f);
  46. pf(v,_SC("[%s] %.14g\n"),name,f);
  47. break;
  48. case OT_USERPOINTER:
  49. pf(v,_SC("[%s] USERPOINTER\n"),name);
  50. break;
  51. case OT_STRING:
  52. sq_getstring(v,-1,&s);
  53. pf(v,_SC("[%s] \"%s\"\n"),name,s);
  54. break;
  55. case OT_TABLE:
  56. pf(v,_SC("[%s] TABLE\n"),name);
  57. break;
  58. case OT_ARRAY:
  59. pf(v,_SC("[%s] ARRAY\n"),name);
  60. break;
  61. case OT_CLOSURE:
  62. pf(v,_SC("[%s] CLOSURE\n"),name);
  63. break;
  64. case OT_NATIVECLOSURE:
  65. pf(v,_SC("[%s] NATIVECLOSURE\n"),name);
  66. break;
  67. case OT_GENERATOR:
  68. pf(v,_SC("[%s] GENERATOR\n"),name);
  69. break;
  70. case OT_USERDATA:
  71. pf(v,_SC("[%s] USERDATA\n"),name);
  72. break;
  73. case OT_THREAD:
  74. pf(v,_SC("[%s] THREAD\n"),name);
  75. break;
  76. case OT_CLASS:
  77. pf(v,_SC("[%s] CLASS\n"),name);
  78. break;
  79. case OT_INSTANCE:
  80. pf(v,_SC("[%s] INSTANCE\n"),name);
  81. break;
  82. case OT_WEAKREF:
  83. pf(v,_SC("[%s] WEAKREF\n"),name);
  84. break;
  85. case OT_BOOL:{
  86. SQBool bval;
  87. sq_getbool(v,-1,&bval);
  88. pf(v,_SC("[%s] %s\n"),name,bval == SQTrue ? _SC("true"):_SC("false"));
  89. }
  90. break;
  91. default: assert(0); break;
  92. }
  93. sq_pop(v,1);
  94. }
  95. }
  96. }
  97. }
  98. static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
  99. {
  100. SQPRINTFUNCTION pf = sq_geterrorfunc(v);
  101. if(pf) {
  102. const SQChar *sErr = 0;
  103. if(sq_gettop(v)>=1) {
  104. if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
  105. pf(v,_SC("\nAN ERROR HAS OCCURRED [%s]\n"),sErr);
  106. }
  107. else{
  108. pf(v,_SC("\nAN ERROR HAS OCCURRED [unknown]\n"));
  109. }
  110. sqstd_printcallstack(v);
  111. }
  112. }
  113. return 0;
  114. }
  115. void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column)
  116. {
  117. SQPRINTFUNCTION pf = sq_geterrorfunc(v);
  118. if(pf) {
  119. pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr);
  120. }
  121. }
  122. void sqstd_seterrorhandlers(HSQUIRRELVM v)
  123. {
  124. sq_setcompilererrorhandler(v,_sqstd_compiler_error);
  125. sq_newclosure(v,_sqstd_aux_printerror,0);
  126. sq_seterrorhandler(v);
  127. }
  128. SQRESULT sqstd_throwerrorf(HSQUIRRELVM v,const SQChar *err,...)
  129. {
  130. SQInteger n=256;
  131. va_list args;
  132. begin:
  133. va_start(args,err);
  134. SQChar *b=sq_getscratchpad(v,n);
  135. SQInteger r=scvsprintf(b,n,err,args);
  136. va_end(args);
  137. if (r>=n) {
  138. n=r+1;//required+null
  139. goto begin;
  140. } else if (r<0) {
  141. return sq_throwerror(v,_SC("@failed to generate formatted error message"));
  142. } else {
  143. return sq_throwerror(v,b);
  144. }
  145. }