iolib.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /*
  2. ** iolib.c
  3. ** Input/output library to LUA
  4. */
  5. char *rcs_iolib="$Id: iolib.c,v 1.46 1996/05/27 14:06:58 roberto Exp roberto $";
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <stdlib.h>
  11. #include <errno.h>
  12. #include "lua.h"
  13. #include "luadebug.h"
  14. #include "lualib.h"
  15. static FILE *in=stdin, *out=stdout;
  16. #ifdef POPEN
  17. FILE *popen();
  18. int pclose();
  19. #else
  20. #define popen(x,y) NULL /* that is, popen always fails */
  21. #define pclose(x) (-1)
  22. #endif
  23. static void pushresult (int i)
  24. {
  25. if (i)
  26. lua_pushnumber (1);
  27. }
  28. static void closeread (void)
  29. {
  30. if (in != stdin)
  31. {
  32. if (pclose(in) == -1)
  33. fclose(in);
  34. in = stdin;
  35. }
  36. }
  37. static void closewrite (void)
  38. {
  39. if (out != stdout)
  40. {
  41. if (pclose(out) == -1)
  42. fclose(out);
  43. out = stdout;
  44. }
  45. }
  46. /*
  47. ** Open a file to read.
  48. ** LUA interface:
  49. ** status = readfrom (filename)
  50. ** where:
  51. ** status = 1 -> success
  52. ** status = nil -> error
  53. */
  54. static void io_readfrom (void)
  55. {
  56. if (lua_getparam (1) == LUA_NOOBJECT)
  57. { /* restore standart input */
  58. closeread();
  59. lua_pushnumber (1);
  60. }
  61. else
  62. {
  63. char *s = lua_check_string(1, "readfrom");
  64. FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
  65. if (fp == NULL)
  66. lua_pushnil();
  67. else
  68. {
  69. closeread();
  70. in = fp;
  71. lua_pushnumber (1);
  72. }
  73. }
  74. }
  75. /*
  76. ** Open a file to write.
  77. ** LUA interface:
  78. ** status = writeto (filename)
  79. ** where:
  80. ** status = 1 -> success
  81. ** status = nil -> error
  82. */
  83. static void io_writeto (void)
  84. {
  85. if (lua_getparam (1) == LUA_NOOBJECT) /* restore standart output */
  86. {
  87. closewrite();
  88. lua_pushnumber (1);
  89. }
  90. else
  91. {
  92. char *s = lua_check_string(1, "writeto");
  93. FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
  94. if (fp)
  95. {
  96. closewrite();
  97. out = fp;
  98. lua_pushnumber (1);
  99. }
  100. }
  101. }
  102. /*
  103. ** Open a file to write appended.
  104. ** LUA interface:
  105. ** status = appendto (filename)
  106. ** where:
  107. ** status = 1 -> success
  108. ** status = nil -> error
  109. */
  110. static void io_appendto (void)
  111. {
  112. char *s = lua_check_string(1, "appendto");
  113. FILE *fp = fopen (s, "a");
  114. if (fp)
  115. {
  116. if (out != stdout) fclose (out);
  117. out = fp;
  118. lua_pushnumber(1);
  119. }
  120. }
  121. static char getformat (char *f, int *just, long *m, int *n)
  122. {
  123. int t;
  124. switch (*f++)
  125. {
  126. case 'q': case 'Q':
  127. case 's': case 'S':
  128. case 'i': case 'I':
  129. t = tolower(*(f-1));
  130. break;
  131. case 'f': case 'F': case 'g': case 'G': case 'e': case 'E':
  132. t = 'f';
  133. break;
  134. default:
  135. t = 0; /* to avoid compiler warnings */
  136. lua_arg_check(0, "read/write (format)");
  137. }
  138. *just = (*f == '<' || *f == '>' || *f == '|') ? *f++ : '>';
  139. if (isdigit(*f))
  140. {
  141. *m = 0;
  142. while (isdigit(*f))
  143. *m = *m*10 + (*f++ - '0');
  144. }
  145. else
  146. *m = -1;
  147. if (*f == '.')
  148. {
  149. f++; /* skip point */
  150. *n = 0;
  151. while (isdigit(*f))
  152. *n = *n*10 + (*f++ - '0');
  153. }
  154. else
  155. *n = -1;
  156. return t;
  157. }
  158. /*
  159. ** Read a variable. On error put nil on stack.
  160. ** LUA interface:
  161. ** variable = read ([format])
  162. **
  163. ** O formato pode ter um dos seguintes especificadores:
  164. **
  165. ** s ou S -> para string
  166. ** f ou F, g ou G, e ou E -> para reais
  167. ** i ou I -> para inteiros
  168. **
  169. ** Estes especificadores podem vir seguidos de numero que representa
  170. ** o numero de campos a serem lidos.
  171. */
  172. static int read_until_char (int del)
  173. {
  174. int c;
  175. while((c = fgetc(in)) != EOF && c != del)
  176. luaI_addchar(c);
  177. return c;
  178. }
  179. static void read_until_blank (void)
  180. {
  181. int c;
  182. while((c = fgetc(in)) != EOF && !isspace(c))
  183. luaI_addchar(c);
  184. if (c != EOF) ungetc(c,in);
  185. }
  186. static void read_m (size_t m)
  187. {
  188. int c;
  189. while (m-- && (c = fgetc(in)) != EOF)
  190. luaI_addchar(c);
  191. }
  192. static void read_free (void)
  193. {
  194. int c;
  195. while (isspace(c=fgetc(in)))
  196. ;
  197. if (c == EOF)
  198. return;
  199. if (c == '\"' || c == '\'')
  200. { /* string */
  201. c = read_until_char(c);
  202. if (c != EOF)
  203. lua_pushstring(luaI_addchar(0));
  204. }
  205. else
  206. {
  207. double d;
  208. char dummy;
  209. char *s;
  210. luaI_addchar(c);
  211. read_until_blank();
  212. s = luaI_addchar(0);
  213. if (sscanf(s, "%lf %c", &d, &dummy) == 1)
  214. lua_pushnumber(d);
  215. else
  216. lua_pushstring(s);
  217. }
  218. }
  219. static void io_read (void)
  220. {
  221. lua_Object o = lua_getparam (1);
  222. luaI_addchar(0); /* initialize buffer */
  223. if (o == LUA_NOOBJECT) /* free format */
  224. read_free();
  225. else /* formatted */
  226. {
  227. long m;
  228. int dummy1, dummy2;
  229. switch (getformat(lua_check_string(1, "read"), &dummy1, &m, &dummy2))
  230. {
  231. case 's':
  232. {
  233. char *s;
  234. if (m < 0)
  235. read_until_blank();
  236. else
  237. read_m(m);
  238. s = luaI_addchar(0);
  239. if ((m >= 0 && strlen(s) == m) || (m < 0 && strlen(s) > 0))
  240. lua_pushstring(s);
  241. break;
  242. }
  243. case 'i': /* can read as float, since it makes no difference to Lua */
  244. case 'f':
  245. {
  246. double d;
  247. int result;
  248. if (m < 0)
  249. result = fscanf(in, "%lf", &d);
  250. else
  251. {
  252. read_m(m);
  253. result = sscanf(luaI_addchar(0), "%lf", &d);
  254. }
  255. if (result == 1)
  256. lua_pushnumber(d);
  257. break;
  258. }
  259. default:
  260. lua_arg_check(0, "read (format)");
  261. }
  262. }
  263. }
  264. /*
  265. ** Read characters until a given one. The delimiter is not read.
  266. */
  267. static void io_readuntil (void)
  268. {
  269. int del, c;
  270. lua_Object p = lua_getparam(1);
  271. luaI_addchar(0); /* initialize buffer */
  272. if (p == LUA_NOOBJECT || lua_isnil(p))
  273. del = EOF;
  274. else
  275. del = *lua_check_string(1, "readuntil");
  276. c = read_until_char(del);
  277. if (c != EOF) ungetc(c,in);
  278. lua_pushstring(luaI_addchar(0));
  279. }
  280. /*
  281. ** Write a variable. On error put 0 on stack, otherwise put 1.
  282. ** LUA interface:
  283. ** status = write (variable [,format])
  284. **
  285. ** O formato pode ter um dos seguintes especificadores:
  286. **
  287. ** s ou S -> para string
  288. ** f ou F, g ou G, e ou E -> para reais
  289. ** i ou I -> para inteiros
  290. **
  291. ** Estes especificadores podem vir seguidos de:
  292. **
  293. ** [?][m][.n]
  294. **
  295. ** onde:
  296. ** ? -> indica justificacao
  297. ** < = esquerda
  298. ** | = centro
  299. ** > = direita (default)
  300. ** m -> numero maximo de campos (se exceder estoura)
  301. ** n -> indica precisao para
  302. ** reais -> numero de casas decimais
  303. ** inteiros -> numero minimo de digitos
  304. ** string -> nao se aplica
  305. */
  306. static int write_fill (size_t n, int c)
  307. {
  308. while (n--)
  309. if (fputc(c, out) == EOF)
  310. return 0;
  311. return 1;
  312. }
  313. static int write_string (char *s, int just, long m)
  314. {
  315. int status;
  316. size_t l = strlen(s);
  317. size_t pre; /* number of blanks before string */
  318. if (m < 0) m = l;
  319. else if (l > m)
  320. {
  321. write_fill(m, '*');
  322. return 0;
  323. }
  324. pre = (just == '<') ? 0 : (just == '>') ? m-l : (m-l)/2;
  325. status = write_fill(pre, ' ');
  326. status = status && fprintf(out, "%s", s) >= 0;
  327. status = status && write_fill(m-(l+pre), ' ');
  328. return status;
  329. }
  330. static int write_quoted (int just, long m)
  331. {
  332. luaI_addchar(0);
  333. luaI_addquoted(lua_check_string(1, "write"));
  334. return write_string(luaI_addchar(0), just, m);
  335. }
  336. static int write_float (int just, long m, int n)
  337. {
  338. char buffer[100];
  339. lua_Object p = lua_getparam(1);
  340. float number;
  341. if (!lua_isnumber(p)) return 0;
  342. number = lua_getnumber(p);
  343. if (n >= 0)
  344. sprintf(buffer, "%.*f", n, number);
  345. else
  346. sprintf(buffer, "%g", number);
  347. return write_string(buffer, just, m);
  348. }
  349. static int write_int (int just, long m, int n)
  350. {
  351. char buffer[100];
  352. lua_Object p = lua_getparam(1);
  353. int number;
  354. if (!lua_isnumber(p)) return 0;
  355. number = (int)lua_getnumber(p);
  356. if (n >= 0)
  357. sprintf(buffer, "%.*d", n, number);
  358. else
  359. sprintf(buffer, "%d", number);
  360. return write_string(buffer, just, m);
  361. }
  362. static void io_write (void)
  363. {
  364. int status = 0;
  365. if (lua_getparam (2) == LUA_NOOBJECT) /* free format */
  366. {
  367. lua_Object o1 = lua_getparam(1);
  368. int t = lua_type(o1);
  369. if (t == LUA_T_NUMBER)
  370. status = fprintf (out, "%g", lua_getnumber(o1)) >= 0;
  371. else if (t == LUA_T_STRING)
  372. status = fprintf (out, "%s", lua_getstring(o1)) >= 0;
  373. }
  374. else /* formated */
  375. {
  376. long m;
  377. int just, n;
  378. switch (getformat(lua_check_string(2, "write"), &just, &m, &n))
  379. {
  380. case 's':
  381. {
  382. lua_Object p = lua_getparam(1);
  383. if (lua_isstring(p))
  384. status = write_string(lua_getstring(p), just, m);
  385. else
  386. status = 0;
  387. break;
  388. }
  389. case 'q':
  390. status = write_quoted(just, m);
  391. break;
  392. case 'f':
  393. status = write_float(just, m, n);
  394. break;
  395. case 'i':
  396. status = write_int(just, m, n);
  397. break;
  398. }
  399. }
  400. if (status)
  401. lua_pushnumber(status);
  402. }
  403. /*
  404. ** Execute a executable program using "system".
  405. ** Return the result of execution.
  406. */
  407. static void io_execute (void)
  408. {
  409. lua_pushnumber(system(lua_check_string(1, "execute")));
  410. }
  411. /*
  412. ** Remove a file. On error return nil.
  413. */
  414. static void io_remove (void)
  415. {
  416. pushresult(remove(lua_check_string(1, "remove")) == 0);
  417. }
  418. static void io_rename (void)
  419. {
  420. char *f1 = lua_check_string(1, "rename");
  421. char *f2 = lua_check_string(2, "rename");
  422. pushresult(rename(f1, f2) == 0);
  423. }
  424. static void io_tmpname (void)
  425. {
  426. lua_pushstring(tmpnam(NULL));
  427. }
  428. static void io_errorno (void)
  429. {
  430. /* lua_pushstring(strerror(errno));*/
  431. }
  432. /*
  433. ** To get an environment variable
  434. */
  435. static void io_getenv (void)
  436. {
  437. char *env = getenv(lua_check_string(1, "getenv"));
  438. lua_pushstring(env); /* if NULL push nil */
  439. }
  440. /*
  441. ** Return user formatted time stamp
  442. */
  443. static void io_date (void)
  444. {
  445. time_t t;
  446. struct tm *tm;
  447. char *s;
  448. char b[BUFSIZ];
  449. if (lua_getparam(1) == LUA_NOOBJECT)
  450. s = "%c";
  451. else
  452. s = lua_check_string(1, "date");
  453. time(&t); tm = localtime(&t);
  454. if (strftime(b,sizeof(b),s,tm))
  455. lua_pushstring(b);
  456. else
  457. lua_error("invalid `date' format");
  458. }
  459. /*
  460. ** To exit
  461. */
  462. static void io_exit (void)
  463. {
  464. lua_Object o = lua_getparam(1);
  465. int code = lua_isnumber(o) ? (int)lua_getnumber(o) : 1;
  466. exit(code);
  467. }
  468. /*
  469. ** To debug a lua program. Start a dialog with the user, interpreting
  470. lua commands until an 'cont'.
  471. */
  472. static void io_debug (void)
  473. {
  474. while (1)
  475. {
  476. char buffer[250];
  477. fprintf(stderr, "lua_debug> ");
  478. if (fgets(buffer, sizeof(buffer), stdin) == 0) return;
  479. if (strcmp(buffer, "cont\n") == 0) return;
  480. lua_dostring(buffer);
  481. }
  482. }
  483. static void lua_printstack (FILE *f)
  484. {
  485. int level = 0;
  486. lua_Object func;
  487. fprintf(f, "Active Stack:\n");
  488. while ((func = lua_stackedfunction(level++)) != LUA_NOOBJECT)
  489. {
  490. char *name;
  491. int currentline;
  492. fprintf(f, "\t");
  493. switch (*lua_getobjname(func, &name))
  494. {
  495. case 'g':
  496. fprintf(f, "function %s", name);
  497. break;
  498. case 'f':
  499. fprintf(f, "`%s' fallback", name);
  500. break;
  501. default:
  502. {
  503. char *filename;
  504. int linedefined;
  505. lua_funcinfo(func, &filename, &linedefined);
  506. if (linedefined == 0)
  507. fprintf(f, "main of %s", filename);
  508. else if (linedefined < 0)
  509. fprintf(f, "%s", filename);
  510. else
  511. fprintf(f, "function (%s:%d)", filename, linedefined);
  512. }
  513. }
  514. if ((currentline = lua_currentline(func)) > 0)
  515. fprintf(f, " at line %d", currentline);
  516. fprintf(f, "\n");
  517. }
  518. }
  519. static void errorfb (void)
  520. {
  521. lua_Object o = lua_getparam(1);
  522. char *s = lua_isstring(o) ? lua_getstring(o) : "(no messsage)";
  523. fprintf(stderr, "lua: %s\n", s);
  524. lua_printstack(stderr);
  525. }
  526. static struct lua_reg iolib[] = {
  527. {"readfrom", io_readfrom},
  528. {"writeto", io_writeto},
  529. {"appendto", io_appendto},
  530. {"read", io_read},
  531. {"readuntil",io_readuntil},
  532. {"write", io_write},
  533. {"execute", io_execute},
  534. {"remove", io_remove},
  535. {"rename", io_rename},
  536. {"tmpname", io_tmpname},
  537. {"ioerror", io_errorno},
  538. {"getenv", io_getenv},
  539. {"date", io_date},
  540. {"exit", io_exit},
  541. {"debug", io_debug},
  542. {"print_stack", errorfb}
  543. };
  544. void iolib_open (void)
  545. {
  546. luaI_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
  547. lua_setfallback("error", errorfb);
  548. }