sqstdsystem.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /* see copyright notice in squirrel.h */
  2. #include <squirrel.h>
  3. #include <string.h>
  4. #include "sqstdblobimpl.h"
  5. #include <time.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <sqstdsystem.h>
  9. #ifdef _WIN32
  10. #include <windows.h>
  11. #endif
  12. #ifdef SQUNICODE
  13. #include <wchar.h>
  14. #define scgetenv _wgetenv
  15. #define scsystem _wsystem
  16. #define scasctime _wasctime
  17. #define scstrftime _wstrftime
  18. #define scremove _wremove
  19. #define screname _wrename
  20. #else
  21. #define scgetenv getenv
  22. #define scsystem system
  23. #define scasctime asctime
  24. #define scstrftime strftime
  25. #define scremove remove
  26. #define screname rename
  27. #endif
  28. SQ_OPT_STRING_STRLEN();
  29. static SQInteger _system_getenv(HSQUIRRELVM v)
  30. {
  31. const SQChar *s;
  32. if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
  33. sq_pushstring(v,scgetenv(s),-1);
  34. return 1;
  35. }
  36. return 0;
  37. }
  38. static SQInteger _system_system(HSQUIRRELVM v)
  39. {
  40. const SQChar *s;
  41. if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){
  42. sq_pushinteger(v,scsystem(s));
  43. return 1;
  44. }
  45. return sq_throwerror(v,_SC("wrong param"));
  46. }
  47. static SQInteger _system_clock(HSQUIRRELVM v)
  48. {
  49. sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC);
  50. return 1;
  51. }
  52. static SQInteger _system_time(HSQUIRRELVM v)
  53. {
  54. time_t t;
  55. time(&t);
  56. sq_pushinteger(v,*((SQInteger *)&t));
  57. return 1;
  58. }
  59. static SQRESULT _system_difftime (HSQUIRRELVM v) {
  60. SQ_FUNC_VARS(v);
  61. SQ_GET_FLOAT(v, 2, t1);
  62. SQ_OPT_FLOAT(v, 3, t2, 0);
  63. sq_pushfloat(v, difftime( (time_t)t1, (time_t)t2));
  64. return 1;
  65. }
  66. static SQInteger _system_remove(HSQUIRRELVM v)
  67. {
  68. const SQChar *s;
  69. sq_getstring(v,2,&s);
  70. if(scremove(s)==-1)
  71. return sq_throwerror(v,_SC("remove() failed"));
  72. return 0;
  73. }
  74. static SQInteger _system_rename(HSQUIRRELVM v)
  75. {
  76. const SQChar *oldn,*newn;
  77. sq_getstring(v,2,&oldn);
  78. sq_getstring(v,3,&newn);
  79. if(screname(oldn,newn)==-1)
  80. return sq_throwerror(v,_SC("rename() failed"));
  81. return 0;
  82. }
  83. static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val)
  84. {
  85. sq_pushstring(v,name,-1);
  86. sq_pushinteger(v,val);
  87. sq_rawset(v,-3);
  88. }
  89. static SQInteger _system_date(HSQUIRRELVM v)
  90. {
  91. SQ_FUNC_VARS(v);
  92. SQ_OPT_STRING(v, 2, arg_format, _SC("%c"));
  93. SQ_OPT_FLOAT(v, 3, arg_time, time(NULL));
  94. time_t t = (time_t)arg_time;
  95. struct tm *stm;
  96. if (*arg_format == _SC('!')) { /* UTC? */
  97. stm = gmtime(&t);
  98. arg_format++; /* skip `!' */
  99. }
  100. else
  101. stm = localtime(&t);
  102. if (stm == NULL) /* invalid date? */
  103. sq_pushnull(v);
  104. else if (scstrcmp(arg_format, _SC("*t")) == 0) {
  105. sq_newtable(v);
  106. _set_integer_slot(v, _SC("sec"), stm->tm_sec);
  107. _set_integer_slot(v, _SC("min"), stm->tm_min);
  108. _set_integer_slot(v, _SC("hour"), stm->tm_hour);
  109. _set_integer_slot(v, _SC("day"), stm->tm_mday);
  110. _set_integer_slot(v, _SC("month"), stm->tm_mon+1);
  111. _set_integer_slot(v, _SC("year"), stm->tm_year+1900);
  112. _set_integer_slot(v, _SC("wday"), stm->tm_wday+1);
  113. _set_integer_slot(v, _SC("yday"), stm->tm_yday+1);
  114. sq_pushliteral(v, _SC("isdst"));
  115. sq_pushbool(v, stm->tm_isdst);
  116. sq_rawset(v, -3);
  117. }
  118. else {
  119. SQChar cc[3];
  120. SQBlob b(0, BLOB_BUFSIZE);
  121. cc[0] = _SC('%'); cc[2] = _SC('\0');
  122. for (; *arg_format; arg_format++) {
  123. if (*arg_format != _SC('%') || *(arg_format + 1) == _SC('\0')) /* no conversion specifier? */
  124. b.WriteChar(*arg_format);
  125. else {
  126. size_t reslen;
  127. SQChar buff[200]; /* should be big enough for any conversion result */
  128. cc[1] = *(++arg_format);
  129. reslen = scstrftime(buff, sizeof(buff)/sizeof(SQChar), cc, stm);
  130. b.Write(buff, reslen);
  131. }
  132. }
  133. sq_pushstring(v, (const SQChar*)b.GetBuf(), b.Len());
  134. }
  135. return 1;
  136. }
  137. static SQRESULT _system_exit (HSQUIRRELVM v) {
  138. SQRESULT status = 0;
  139. SQ_FUNC_VARS(v);
  140. if(_top_ > 1){
  141. SQObjectType ptype = sq_gettype(v, 1);
  142. if (ptype == OT_BOOL){
  143. SQ_GET_BOOL(v,2, b);
  144. status = b ? EXIT_SUCCESS : EXIT_FAILURE;
  145. }
  146. else
  147. sq_getinteger(v, 2, &status);
  148. SQ_OPT_BOOL(v, 3, bclose, false);
  149. if (bclose) sq_close(v);
  150. }
  151. exit(status);
  152. }
  153. #if defined(SC_USE_MKSTEMP)
  154. #include <unistd.h>
  155. #define SQ_TMPNAMBUFSIZE 32
  156. #define sq_tmpnam(b,e) { \
  157. strcpy(b, "/tmp/lua_XXXXXX"); \
  158. e = mkstemp(b); \
  159. if (e != -1) close(e); \
  160. e = (e == -1); }
  161. #else
  162. #define SQ_TMPNAMBUFSIZE L_tmpnam
  163. #define sq_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
  164. #endif
  165. static SQRESULT _system_tmpname (HSQUIRRELVM v) {
  166. char buff[SQ_TMPNAMBUFSIZE];
  167. int err;
  168. sq_tmpnam(buff, err);
  169. if (err)
  170. return sq_throwerror(v, "unable to generate a unique filename");
  171. sq_pushstring(v, buff, -1);
  172. return 1;
  173. }
  174. #include <locale.h>
  175. static SQRESULT _system_setlocale (HSQUIRRELVM v) {
  176. static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
  177. LC_NUMERIC, LC_TIME};
  178. static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
  179. "numeric", "time", NULL};
  180. SQ_FUNC_VARS(v);
  181. SQ_OPT_STRING(v, 2, l, NULL);
  182. SQ_OPT_STRING(v, 3, name, "all");
  183. for (int i=0; catnames[i]; i++)
  184. if (strcmp(catnames[i], name) == 0){
  185. sq_pushstring(v, setlocale(cat[i], l), -1);
  186. return 1;
  187. }
  188. return sq_throwerror(v, "invalid option %s for param %d", name, 3);
  189. }
  190. /*-------------------------------------------------------------------------*\
  191. * Sleep for n seconds.
  192. \*-------------------------------------------------------------------------*/
  193. static SQRESULT _system_sleep(HSQUIRRELVM v)
  194. {
  195. SQ_FUNC_VARS_NO_TOP(v);
  196. SQ_GET_FLOAT(v, 2, n);
  197. #ifdef _WIN32
  198. Sleep((int)(n*1000));
  199. #else
  200. struct timespec t, r;
  201. t.tv_sec = (int) n;
  202. n -= t.tv_sec;
  203. t.tv_nsec = (int) (n * 1000000000);
  204. if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999;
  205. while (nanosleep(&t, &r) != 0) {
  206. t.tv_sec = r.tv_sec;
  207. t.tv_nsec = r.tv_nsec;
  208. }
  209. #endif
  210. return 0;
  211. }
  212. #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
  213. static SQRegFunction systemlib_funcs[]={
  214. _DECL_FUNC(getenv,2,_SC(".s")),
  215. _DECL_FUNC(system,2,_SC(".s")),
  216. _DECL_FUNC(clock,0,NULL),
  217. _DECL_FUNC(time,1,NULL),
  218. _DECL_FUNC(difftime,-2,_SC(".nn")),
  219. _DECL_FUNC(date,-1,_SC(".sn")),
  220. _DECL_FUNC(remove,2,_SC(".s")),
  221. _DECL_FUNC(rename,3,_SC(".ss")),
  222. _DECL_FUNC(exit, -1,_SC(". b|i b")),
  223. _DECL_FUNC(sleep, 2,_SC(".n")),
  224. _DECL_FUNC(tmpname,1,_SC(".")),
  225. _DECL_FUNC(setlocale,-1,_SC(".ss")),
  226. {0,0}
  227. };
  228. #undef _DECL_FUNC
  229. SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
  230. {
  231. sq_pushstring(v,_SC("os"),-1);
  232. sq_newclass(v,SQFalse);
  233. SQInteger i=0;
  234. while(systemlib_funcs[i].name!=0)
  235. {
  236. sq_pushstring(v,systemlib_funcs[i].name,-1);
  237. sq_newclosure(v,systemlib_funcs[i].f,0);
  238. sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask);
  239. sq_setnativeclosurename(v,-1,systemlib_funcs[i].name);
  240. sq_newslot(v,-3,SQFalse);
  241. i++;
  242. }
  243. sq_newslot(v,-3,SQTrue); //insert os
  244. return 1;
  245. }