/* ** iolib.c ** Input/output library to LUA ** ** Waldemar Celes Filho ** TeCGraf - PUC-Rio ** 19 May 93 */ #include #include #include #include #ifdef __GNUC__ #include #endif #include "lua.h" static FILE *in=stdin, *out=stdout; /* ** Open a file to read. ** LUA interface: ** status = readfrom (filename) ** where: ** status = 1 -> success ** status = 0 -> error */ static void io_readfrom (void) { lua_Object o = lua_getparam (1); if (o == NULL) /* restore standart input */ { if (in != stdin) { fclose (in); in = stdin; } lua_pushnumber (1); } else { if (!lua_isstring (o)) { lua_error ("incorrect argument to function 'readfrom`"); lua_pushnumber (0); } else { FILE *fp = fopen (lua_getstring(o),"r"); if (fp == NULL) { lua_pushnumber (0); } else { if (in != stdin) fclose (in); in = fp; lua_pushnumber (1); } } } } /* ** Open a file to write. ** LUA interface: ** status = writeto (filename) ** where: ** status = 1 -> success ** status = 0 -> error */ static void io_writeto (void) { lua_Object o = lua_getparam (1); if (o == NULL) /* restore standart output */ { if (out != stdout) { fclose (out); out = stdout; } lua_pushnumber (1); } else { if (!lua_isstring (o)) { lua_error ("incorrect argument to function 'writeto`"); lua_pushnumber (0); } else { FILE *fp = fopen (lua_getstring(o),"w"); if (fp == NULL) { lua_pushnumber (0); } else { if (out != stdout) fclose (out); out = fp; lua_pushnumber (1); } } } } /* ** Read a variable. On error put nil on stack. ** LUA interface: ** variable = read ([format]) ** ** O formato pode ter um dos seguintes especificadores: ** ** s ou S -> para string ** f ou F, g ou G, e ou E -> para reais ** i ou I -> para inteiros ** ** Estes especificadores podem vir seguidos de numero que representa ** o numero de campos a serem lidos. */ static void io_read (void) { lua_Object o = lua_getparam (1); if (o == NULL) /* free format */ { int c; char s[256]; while (isspace(c=fgetc(in))) ; if (c == '\"') { if (fscanf (in, "%[^\"]\"", s) != 1) { lua_pushnil (); return; } } else if (c == '\'') { if (fscanf (in, "%[^\']\'", s) != 1) { lua_pushnil (); return; } } else { char *ptr; double d; ungetc (c, in); if (fscanf (in, "%s", s) != 1) { lua_pushnil (); return; } d = strtod (s, &ptr); if (!(*ptr)) { lua_pushnumber (d); return; } } lua_pushstring (s); return; } else /* formatted */ { char *e = lua_getstring(o); char t; int m=0; while (isspace(*e)) e++; t = *e++; while (isdigit(*e)) m = m*10 + (*e++ - '0'); if (m > 0) { char f[80]; char s[256]; sprintf (f, "%%%ds", m); fscanf (in, f, s); switch (tolower(t)) { case 'i': { long int l; sscanf (s, "%ld", &l); lua_pushnumber(l); } break; case 'f': case 'g': case 'e': { float f; sscanf (s, "%f", &f); lua_pushnumber(f); } break; default: lua_pushstring(s); break; } } else { switch (tolower(t)) { case 'i': { long int l; fscanf (in, "%ld", &l); lua_pushnumber(l); } break; case 'f': case 'g': case 'e': { float f; fscanf (in, "%f", &f); lua_pushnumber(f); } break; default: { char s[256]; fscanf (in, "%s", s); lua_pushstring(s); } break; } } } } /* ** Write a variable. On error put 0 on stack, otherwise put 1. ** LUA interface: ** status = write (variable [,format]) ** ** O formato pode ter um dos seguintes especificadores: ** ** s ou S -> para string ** f ou F, g ou G, e ou E -> para reais ** i ou I -> para inteiros ** ** Estes especificadores podem vir seguidos de: ** ** [?][m][.n] ** ** onde: ** ? -> indica justificacao ** < = esquerda ** | = centro ** > = direita (default) ** m -> numero maximo de campos (se exceder estoura) ** n -> indica precisao para ** reais -> numero de casas decimais ** inteiros -> numero minimo de digitos ** string -> nao se aplica */ static char *buildformat (char *e, lua_Object o) { static char buffer[512]; static char f[80]; char *string = &buffer[255]; char t, j='r'; int m=0, n=0, l; while (isspace(*e)) e++; t = *e++; if (*e == '<' || *e == '|' || *e == '>') j = *e++; while (isdigit(*e)) m = m*10 + (*e++ - '0'); e++; /* skip point */ while (isdigit(*e)) n = n*10 + (*e++ - '0'); sprintf(f,"%%"); if (j == '<' || j == '|') sprintf(strchr(f,0),"-"); if (m != 0) sprintf(strchr(f,0),"%d", m); if (n != 0) sprintf(strchr(f,0),".%d", n); sprintf(strchr(f,0), "%c", t); switch (tolower(t)) { case 'i': t = 'i'; sprintf (string, f, (long int)lua_getnumber(o)); break; case 'f': case 'g': case 'e': t = 'f'; sprintf (string, f, (float)lua_getnumber(o)); break; case 's': t = 's'; sprintf (string, f, lua_getstring(o)); break; default: return ""; } l = strlen(string); if (m!=0 && l>m) { int i; for (i=0; i