iolib.c 11 KB

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