diff options
| author | The Lua team <lua@tecgraf.puc-rio.br> | 1993-07-28 10:18:00 -0300 |
|---|---|---|
| committer | The Lua team <lua@tecgraf.puc-rio.br> | 1993-07-28 10:18:00 -0300 |
| commit | cd05d9c5cb69020c069f037ba7f243f705d0a48a (patch) | |
| tree | cb7f08c0684c10970a528984741047fb3babadd3 /iolib.c | |
| download | lua-cd05d9c5cb69020c069f037ba7f243f705d0a48a.tar.gz lua-cd05d9c5cb69020c069f037ba7f243f705d0a48a.tar.bz2 lua-cd05d9c5cb69020c069f037ba7f243f705d0a48a.zip | |
oldest known commit
Diffstat (limited to 'iolib.c')
| -rw-r--r-- | iolib.c | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/iolib.c b/iolib.c new file mode 100644 index 00000000..174dd501 --- /dev/null +++ b/iolib.c | |||
| @@ -0,0 +1,401 @@ | |||
| 1 | /* | ||
| 2 | ** iolib.c | ||
| 3 | ** Input/output library to LUA | ||
| 4 | ** | ||
| 5 | ** Waldemar Celes Filho | ||
| 6 | ** TeCGraf - PUC-Rio | ||
| 7 | ** 19 May 93 | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <stdlib.h> | ||
| 11 | #include <string.h> | ||
| 12 | #include <stdio.h> | ||
| 13 | #include <ctype.h> | ||
| 14 | #ifdef __GNUC__ | ||
| 15 | #include <floatingpoint.h> | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #include "lua.h" | ||
| 19 | |||
| 20 | static FILE *in=stdin, *out=stdout; | ||
| 21 | |||
| 22 | /* | ||
| 23 | ** Open a file to read. | ||
| 24 | ** LUA interface: | ||
| 25 | ** status = readfrom (filename) | ||
| 26 | ** where: | ||
| 27 | ** status = 1 -> success | ||
| 28 | ** status = 0 -> error | ||
| 29 | */ | ||
| 30 | static void io_readfrom (void) | ||
| 31 | { | ||
| 32 | lua_Object o = lua_getparam (1); | ||
| 33 | if (o == NULL) /* restore standart input */ | ||
| 34 | { | ||
| 35 | if (in != stdin) | ||
| 36 | { | ||
| 37 | fclose (in); | ||
| 38 | in = stdin; | ||
| 39 | } | ||
| 40 | lua_pushnumber (1); | ||
| 41 | } | ||
| 42 | else | ||
| 43 | { | ||
| 44 | if (!lua_isstring (o)) | ||
| 45 | { | ||
| 46 | lua_error ("incorrect argument to function 'readfrom`"); | ||
| 47 | lua_pushnumber (0); | ||
| 48 | } | ||
| 49 | else | ||
| 50 | { | ||
| 51 | FILE *fp = fopen (lua_getstring(o),"r"); | ||
| 52 | if (fp == NULL) | ||
| 53 | { | ||
| 54 | lua_pushnumber (0); | ||
| 55 | } | ||
| 56 | else | ||
| 57 | { | ||
| 58 | if (in != stdin) fclose (in); | ||
| 59 | in = fp; | ||
| 60 | lua_pushnumber (1); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | |||
| 67 | /* | ||
| 68 | ** Open a file to write. | ||
| 69 | ** LUA interface: | ||
| 70 | ** status = writeto (filename) | ||
| 71 | ** where: | ||
| 72 | ** status = 1 -> success | ||
| 73 | ** status = 0 -> error | ||
| 74 | */ | ||
| 75 | static void io_writeto (void) | ||
| 76 | { | ||
| 77 | lua_Object o = lua_getparam (1); | ||
| 78 | if (o == NULL) /* restore standart output */ | ||
| 79 | { | ||
| 80 | if (out != stdout) | ||
| 81 | { | ||
| 82 | fclose (out); | ||
| 83 | out = stdout; | ||
| 84 | } | ||
| 85 | lua_pushnumber (1); | ||
| 86 | } | ||
| 87 | else | ||
| 88 | { | ||
| 89 | if (!lua_isstring (o)) | ||
| 90 | { | ||
| 91 | lua_error ("incorrect argument to function 'writeto`"); | ||
| 92 | lua_pushnumber (0); | ||
| 93 | } | ||
| 94 | else | ||
| 95 | { | ||
| 96 | FILE *fp = fopen (lua_getstring(o),"w"); | ||
| 97 | if (fp == NULL) | ||
| 98 | { | ||
| 99 | lua_pushnumber (0); | ||
| 100 | } | ||
| 101 | else | ||
| 102 | { | ||
| 103 | if (out != stdout) fclose (out); | ||
| 104 | out = fp; | ||
| 105 | lua_pushnumber (1); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | |||
| 112 | /* | ||
| 113 | ** Read a variable. On error put nil on stack. | ||
| 114 | ** LUA interface: | ||
| 115 | ** variable = read ([format]) | ||
| 116 | ** | ||
| 117 | ** O formato pode ter um dos seguintes especificadores: | ||
| 118 | ** | ||
| 119 | ** s ou S -> para string | ||
| 120 | ** f ou F, g ou G, e ou E -> para reais | ||
| 121 | ** i ou I -> para inteiros | ||
| 122 | ** | ||
| 123 | ** Estes especificadores podem vir seguidos de numero que representa | ||
| 124 | ** o numero de campos a serem lidos. | ||
| 125 | */ | ||
| 126 | static void io_read (void) | ||
| 127 | { | ||
| 128 | lua_Object o = lua_getparam (1); | ||
| 129 | if (o == NULL) /* free format */ | ||
| 130 | { | ||
| 131 | int c; | ||
| 132 | char s[256]; | ||
| 133 | while (isspace(c=fgetc(in))) | ||
| 134 | ; | ||
| 135 | if (c == '\"') | ||
| 136 | { | ||
| 137 | if (fscanf (in, "%[^\"]\"", s) != 1) | ||
| 138 | { | ||
| 139 | lua_pushnil (); | ||
| 140 | return; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | else if (c == '\'') | ||
| 144 | { | ||
| 145 | if (fscanf (in, "%[^\']\'", s) != 1) | ||
| 146 | { | ||
| 147 | lua_pushnil (); | ||
| 148 | return; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | else | ||
| 152 | { | ||
| 153 | char *ptr; | ||
| 154 | double d; | ||
| 155 | ungetc (c, in); | ||
| 156 | if (fscanf (in, "%s", s) != 1) | ||
| 157 | { | ||
| 158 | lua_pushnil (); | ||
| 159 | return; | ||
| 160 | } | ||
| 161 | d = strtod (s, &ptr); | ||
| 162 | if (!(*ptr)) | ||
| 163 | { | ||
| 164 | lua_pushnumber (d); | ||
| 165 | return; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | lua_pushstring (s); | ||
| 169 | return; | ||
| 170 | } | ||
| 171 | else /* formatted */ | ||
| 172 | { | ||
| 173 | char *e = lua_getstring(o); | ||
| 174 | char t; | ||
| 175 | int m=0; | ||
| 176 | while (isspace(*e)) e++; | ||
| 177 | t = *e++; | ||
| 178 | while (isdigit(*e)) | ||
| 179 | m = m*10 + (*e++ - '0'); | ||
| 180 | |||
| 181 | if (m > 0) | ||
| 182 | { | ||
| 183 | char f[80]; | ||
| 184 | char s[256]; | ||
| 185 | sprintf (f, "%%%ds", m); | ||
| 186 | fscanf (in, f, s); | ||
| 187 | switch (tolower(t)) | ||
| 188 | { | ||
| 189 | case 'i': | ||
| 190 | { | ||
| 191 | long int l; | ||
| 192 | sscanf (s, "%ld", &l); | ||
| 193 | lua_pushnumber(l); | ||
| 194 | } | ||
| 195 | break; | ||
| 196 | case 'f': case 'g': case 'e': | ||
| 197 | { | ||
| 198 | float f; | ||
| 199 | sscanf (s, "%f", &f); | ||
| 200 | lua_pushnumber(f); | ||
| 201 | } | ||
| 202 | break; | ||
| 203 | default: | ||
| 204 | lua_pushstring(s); | ||
| 205 | break; | ||
| 206 | } | ||
| 207 | } | ||
| 208 | else | ||
| 209 | { | ||
| 210 | switch (tolower(t)) | ||
| 211 | { | ||
| 212 | case 'i': | ||
| 213 | { | ||
| 214 | long int l; | ||
| 215 | fscanf (in, "%ld", &l); | ||
| 216 | lua_pushnumber(l); | ||
| 217 | } | ||
| 218 | break; | ||
| 219 | case 'f': case 'g': case 'e': | ||
| 220 | { | ||
| 221 | float f; | ||
| 222 | fscanf (in, "%f", &f); | ||
| 223 | lua_pushnumber(f); | ||
| 224 | } | ||
| 225 | break; | ||
| 226 | default: | ||
| 227 | { | ||
| 228 | char s[256]; | ||
| 229 | fscanf (in, "%s", s); | ||
| 230 | lua_pushstring(s); | ||
| 231 | } | ||
| 232 | break; | ||
| 233 | } | ||
| 234 | } | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | |||
| 239 | /* | ||
| 240 | ** Write a variable. On error put 0 on stack, otherwise put 1. | ||
| 241 | ** LUA interface: | ||
| 242 | ** status = write (variable [,format]) | ||
| 243 | ** | ||
| 244 | ** O formato pode ter um dos seguintes especificadores: | ||
| 245 | ** | ||
| 246 | ** s ou S -> para string | ||
| 247 | ** f ou F, g ou G, e ou E -> para reais | ||
| 248 | ** i ou I -> para inteiros | ||
| 249 | ** | ||
| 250 | ** Estes especificadores podem vir seguidos de: | ||
| 251 | ** | ||
| 252 | ** [?][m][.n] | ||
| 253 | ** | ||
| 254 | ** onde: | ||
| 255 | ** ? -> indica justificacao | ||
| 256 | ** < = esquerda | ||
| 257 | ** | = centro | ||
| 258 | ** > = direita (default) | ||
| 259 | ** m -> numero maximo de campos (se exceder estoura) | ||
| 260 | ** n -> indica precisao para | ||
| 261 | ** reais -> numero de casas decimais | ||
| 262 | ** inteiros -> numero minimo de digitos | ||
| 263 | ** string -> nao se aplica | ||
| 264 | */ | ||
| 265 | static char *buildformat (char *e, lua_Object o) | ||
| 266 | { | ||
| 267 | static char buffer[512]; | ||
| 268 | static char f[80]; | ||
| 269 | char *string = &buffer[255]; | ||
| 270 | char t, j='r'; | ||
| 271 | int m=0, n=0, l; | ||
| 272 | while (isspace(*e)) e++; | ||
| 273 | t = *e++; | ||
| 274 | if (*e == '<' || *e == '|' || *e == '>') j = *e++; | ||
| 275 | while (isdigit(*e)) | ||
| 276 | m = m*10 + (*e++ - '0'); | ||
| 277 | e++; /* skip point */ | ||
| 278 | while (isdigit(*e)) | ||
| 279 | n = n*10 + (*e++ - '0'); | ||
| 280 | |||
| 281 | sprintf(f,"%%"); | ||
| 282 | if (j == '<' || j == '|') sprintf(strchr(f,0),"-"); | ||
| 283 | if (m != 0) sprintf(strchr(f,0),"%d", m); | ||
| 284 | if (n != 0) sprintf(strchr(f,0),".%d", n); | ||
| 285 | sprintf(strchr(f,0), "%c", t); | ||
| 286 | switch (tolower(t)) | ||
| 287 | { | ||
| 288 | case 'i': t = 'i'; | ||
| 289 | sprintf (string, f, (long int)lua_getnumber(o)); | ||
| 290 | break; | ||
| 291 | case 'f': case 'g': case 'e': t = 'f'; | ||
| 292 | sprintf (string, f, (float)lua_getnumber(o)); | ||
| 293 | break; | ||
| 294 | case 's': t = 's'; | ||
| 295 | sprintf (string, f, lua_getstring(o)); | ||
| 296 | break; | ||
| 297 | default: return ""; | ||
| 298 | } | ||
| 299 | l = strlen(string); | ||
| 300 | if (m!=0 && l>m) | ||
| 301 | { | ||
| 302 | int i; | ||
| 303 | for (i=0; i<m; i++) | ||
| 304 | string[i] = '*'; | ||
| 305 | string[i] = 0; | ||
| 306 | } | ||
| 307 | else if (m!=0 && j=='|') | ||
| 308 | { | ||
| 309 | int i=l-1; | ||
| 310 | while (isspace(string[i])) i--; | ||
| 311 | string -= (m-i) / 2; | ||
| 312 | i=0; | ||
| 313 | while (string[i]==0) string[i++] = ' '; | ||
| 314 | string[l] = 0; | ||
| 315 | } | ||
| 316 | return string; | ||
| 317 | } | ||
| 318 | static void io_write (void) | ||
| 319 | { | ||
| 320 | lua_Object o1 = lua_getparam (1); | ||
| 321 | lua_Object o2 = lua_getparam (2); | ||
| 322 | if (o1 == NULL) /* new line */ | ||
| 323 | { | ||
| 324 | fprintf (out, "\n"); | ||
| 325 | lua_pushnumber(1); | ||
| 326 | } | ||
| 327 | else if (o2 == NULL) /* free format */ | ||
| 328 | { | ||
| 329 | int status=0; | ||
| 330 | if (lua_isnumber(o1)) | ||
| 331 | status = fprintf (out, "%g", lua_getnumber(o1)); | ||
| 332 | else if (lua_isstring(o1)) | ||
| 333 | status = fprintf (out, "%s", lua_getstring(o1)); | ||
| 334 | lua_pushnumber(status); | ||
| 335 | } | ||
| 336 | else /* formated */ | ||
| 337 | { | ||
| 338 | if (!lua_isstring(o2)) | ||
| 339 | { | ||
| 340 | lua_error ("incorrect format to function `write'"); | ||
| 341 | lua_pushnumber(0); | ||
| 342 | return; | ||
| 343 | } | ||
| 344 | lua_pushnumber(fprintf (out, "%s", buildformat(lua_getstring(o2),o1))); | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | /* | ||
| 349 | ** Execute a executable program using "sustem". | ||
| 350 | ** On error put 0 on stack, otherwise put 1. | ||
| 351 | */ | ||
| 352 | void io_execute (void) | ||
| 353 | { | ||
| 354 | lua_Object o = lua_getparam (1); | ||
| 355 | if (o == NULL || !lua_isstring (o)) | ||
| 356 | { | ||
| 357 | lua_error ("incorrect argument to function 'execute`"); | ||
| 358 | lua_pushnumber (0); | ||
| 359 | } | ||
| 360 | else | ||
| 361 | { | ||
| 362 | system(lua_getstring(o)); | ||
| 363 | lua_pushnumber (1); | ||
| 364 | } | ||
| 365 | return; | ||
| 366 | } | ||
| 367 | |||
| 368 | /* | ||
| 369 | ** Remove a file. | ||
| 370 | ** On error put 0 on stack, otherwise put 1. | ||
| 371 | */ | ||
| 372 | void io_remove (void) | ||
| 373 | { | ||
| 374 | lua_Object o = lua_getparam (1); | ||
| 375 | if (o == NULL || !lua_isstring (o)) | ||
| 376 | { | ||
| 377 | lua_error ("incorrect argument to function 'execute`"); | ||
| 378 | lua_pushnumber (0); | ||
| 379 | } | ||
| 380 | else | ||
| 381 | { | ||
| 382 | if (remove(lua_getstring(o)) == 0) | ||
| 383 | lua_pushnumber (1); | ||
| 384 | else | ||
| 385 | lua_pushnumber (0); | ||
| 386 | } | ||
| 387 | return; | ||
| 388 | } | ||
| 389 | |||
| 390 | /* | ||
| 391 | ** Open io library | ||
| 392 | */ | ||
| 393 | void iolib_open (void) | ||
| 394 | { | ||
| 395 | lua_register ("readfrom", io_readfrom); | ||
| 396 | lua_register ("writeto", io_writeto); | ||
| 397 | lua_register ("read", io_read); | ||
| 398 | lua_register ("write", io_write); | ||
| 399 | lua_register ("execute", io_execute); | ||
| 400 | lua_register ("remove", io_remove); | ||
| 401 | } | ||
