aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-05-21 12:24:21 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2014-05-21 12:24:21 -0300
commite966e5379195a3414c0e8f6be6e25052702305ff (patch)
tree3207b4865ee1819e268d6577c377738d94d52603
parentc4eff10322f5e1e8213c9004f8b91c3c7bd36e3f (diff)
downloadlua-e966e5379195a3414c0e8f6be6e25052702305ff.tar.gz
lua-e966e5379195a3414c0e8f6be6e25052702305ff.tar.bz2
lua-e966e5379195a3414c0e8f6be6e25052702305ff.zip
no more use of 'scanf' for reading numbers
-rw-r--r--liolib.c98
-rw-r--r--luaconf.h11
2 files changed, 82 insertions, 27 deletions
diff --git a/liolib.c b/liolib.c
index 5b50bbf1..82fd49f3 100644
--- a/liolib.c
+++ b/liolib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: liolib.c,v 2.123 2014/05/13 19:40:28 roberto Exp roberto $ 2** $Id: liolib.c,v 2.124 2014/05/15 15:21:06 roberto Exp $
3** Standard I/O (and system) library 3** Standard I/O (and system) library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -15,7 +15,9 @@
15#endif 15#endif
16 16
17 17
18#include <ctype.h>
18#include <errno.h> 19#include <errno.h>
20#include <locale.h>
19#include <stdio.h> 21#include <stdio.h>
20#include <stdlib.h> 22#include <stdlib.h>
21#include <string.h> 23#include <string.h>
@@ -361,26 +363,91 @@ static int io_lines (lua_State *L) {
361*/ 363*/
362 364
363 365
364static int read_integer (lua_State *L, FILE *f) { 366/* maximum length of a numeral */
365 lua_Integer d; 367#define MAXRN 200
366 if (fscanf(f, LUA_INTEGER_SCAN, &d) == 1) { 368
367 lua_pushinteger(L, d); 369/* auxiliary structure used by 'read_number' */
368 return 1; 370typedef struct {
369 } 371 FILE *f; /* file being read */
372 int c; /* current character (look ahead) */
373 int n; /* number of elements in buffer 'buff' */
374 char buff[MAXRN];
375} RN;
376
377
378/*
379** Add current char to buffer (if not out of space) and read next one
380*/
381static int nextc (RN *rn) {
382 if (rn->n >= MAXRN) /* buffer overflow? */
383 return 0; /* fail */
370 else { 384 else {
371 lua_pushnil(L); /* "result" to be removed */ 385 rn->buff[rn->n++] = rn->c; /* save current char */
372 return 0; /* read fails */ 386 rn->c = l_getc(rn->f); /* read next one */
387 return 1;
373 } 388 }
374} 389}
375 390
376 391
392/*
393** Accept current char if it is in 'set' (of size 1 or 2)
394*/
395static int test2 (RN *rn, const char *set) {
396 if (rn->c == set[0] || (rn->c == set[1] && rn->c != '\0'))
397 return nextc(rn);
398 else return 0;
399}
400
401
402/*
403** Read a sequence of (hexa)digits
404*/
405static int readdigits (RN *rn, int hexa) {
406 int count = 0;
407 while ((hexa ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn))
408 count++;
409 return count;
410}
411
412
413/* access to locale "radix character" (decimal point) */
414#if !defined(getlocaledecpoint)
415#define getlocaledecpoint() (localeconv()->decimal_point[0])
416#endif
417
418
419/*
420** Read a number: first reads a valid prefix of a numeral into a buffer.
421** Then it calls 'lua_strtonum' to check whether the format is correct
422** and to convert it to a Lua number
423*/
377static int read_number (lua_State *L, FILE *f) { 424static int read_number (lua_State *L, FILE *f) {
378 lua_Number d; 425 RN rn;
379 if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { 426 int count = 0;
380 lua_pushnumber(L, d); 427 int hexa = 0;
381 return 1; 428 char decp[2] = ".";
429 rn.f = f; rn.n = 0;
430 decp[0] = getlocaledecpoint(); /* get decimal point from locale */
431 l_lockfile(rn.f);
432 do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
433 test2(&rn, "-+"); /* optional signal */
434 if (test2(&rn, "0")) {
435 if (test2(&rn, "xX")) hexa = 1; /* numeral is hexadecimal */
436 else count = 1; /* count initial '0' as a valid digit */
382 } 437 }
383 else { 438 count += readdigits(&rn, hexa); /* integral part */
439 if (test2(&rn, decp)) /* decimal point? */
440 count += readdigits(&rn, hexa); /* fractionary part */
441 if (count > 0 && test2(&rn, (hexa ? "pP" : "eE"))) { /* exponent mark? */
442 test2(&rn, "-+"); /* exponent signal */
443 readdigits(&rn, 0); /* exponent digits */
444 }
445 ungetc(rn.c, rn.f); /* unread look-ahead char */
446 l_unlockfile(rn.f);
447 rn.buff[rn.n] = '\0'; /* finish string */
448 if (lua_strtonum(L, rn.buff)) /* is this a valid number? */
449 return 1; /* ok */
450 else { /* invalid format */
384 lua_pushnil(L); /* "result" to be removed */ 451 lua_pushnil(L); /* "result" to be removed */
385 return 0; /* read fails */ 452 return 0; /* read fails */
386 } 453 }
@@ -456,9 +523,6 @@ static int g_read (lua_State *L, FILE *f, int first) {
456 const char *p = luaL_checkstring(L, n); 523 const char *p = luaL_checkstring(L, n);
457 if (*p == '*') p++; /* skip optional '*' (for compatibility) */ 524 if (*p == '*') p++; /* skip optional '*' (for compatibility) */
458 switch (*p) { 525 switch (*p) {
459 case 'i': /* integer */
460 success = read_integer(L, f);
461 break;
462 case 'n': /* number */ 526 case 'n': /* number */
463 success = read_number(L, f); 527 success = read_number(L, f);
464 break; 528 break;
diff --git a/luaconf.h b/luaconf.h
index dd5e7280..40bb5ef5 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: luaconf.h,v 1.201 2014/05/11 13:03:48 roberto Exp roberto $ 2** $Id: luaconf.h,v 1.202 2014/05/15 15:24:32 roberto Exp roberto $
3** Configuration file for Lua 3** Configuration file for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -431,7 +431,6 @@
431@@ over a floating number. 431@@ over a floating number.
432** 432**
433@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. 433@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
434@@ LUA_NUMBER_SCAN is the format for reading floats.
435@@ LUA_NUMBER_FMT is the format for writing floats. 434@@ LUA_NUMBER_FMT is the format for writing floats.
436@@ lua_number2str converts a float to a string. 435@@ lua_number2str converts a float to a string.
437** 436**
@@ -447,7 +446,6 @@
447#define LUAI_UACNUMBER double 446#define LUAI_UACNUMBER double
448 447
449#define LUA_NUMBER_FRMLEN "" 448#define LUA_NUMBER_FRMLEN ""
450#define LUA_NUMBER_SCAN "%f"
451#define LUA_NUMBER_FMT "%.7g" 449#define LUA_NUMBER_FMT "%.7g"
452 450
453#define l_mathop(op) op##f 451#define l_mathop(op) op##f
@@ -462,7 +460,6 @@
462#define LUAI_UACNUMBER long double 460#define LUAI_UACNUMBER long double
463 461
464#define LUA_NUMBER_FRMLEN "L" 462#define LUA_NUMBER_FRMLEN "L"
465#define LUA_NUMBER_SCAN "%Lf"
466#define LUA_NUMBER_FMT "%.19Lg" 463#define LUA_NUMBER_FMT "%.19Lg"
467 464
468#define l_mathop(op) op##l 465#define l_mathop(op) op##l
@@ -476,7 +473,6 @@
476#define LUAI_UACNUMBER double 473#define LUAI_UACNUMBER double
477 474
478#define LUA_NUMBER_FRMLEN "" 475#define LUA_NUMBER_FRMLEN ""
479#define LUA_NUMBER_SCAN "%lf"
480#define LUA_NUMBER_FMT "%.14g" 476#define LUA_NUMBER_FMT "%.14g"
481 477
482#define l_mathop(op) op 478#define l_mathop(op) op
@@ -552,7 +548,6 @@
552@@ LUAI_UACINT is the result of an 'usual argument conversion' 548@@ LUAI_UACINT is the result of an 'usual argument conversion'
553@@ over a lUA_INTEGER. 549@@ over a lUA_INTEGER.
554@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. 550@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
555@@ LUA_INTEGER_SCAN is the format for reading integers.
556@@ LUA_INTEGER_FMT is the format for writing integers. 551@@ LUA_INTEGER_FMT is the format for writing integers.
557@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. 552@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
558@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. 553@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
@@ -563,7 +558,6 @@
563 558
564/* The following definitions are good for most cases here */ 559/* The following definitions are good for most cases here */
565 560
566#define LUA_INTEGER_SCAN "%" LUA_INTEGER_FRMLEN "d"
567#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" 561#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
568#define lua_integer2str(s,n) sprintf((s), LUA_INTEGER_FMT, (n)) 562#define lua_integer2str(s,n) sprintf((s), LUA_INTEGER_FMT, (n))
569 563
@@ -634,9 +628,6 @@
634#undef LUAI_UACINT 628#undef LUAI_UACINT
635#define LUAI_UACINT int 629#define LUAI_UACINT int
636 630
637#undef LUA_INTEGER_SCAN
638#define LUA_INTEGER_SCAN "%hd"
639
640#undef LUAI_MAXSTACK 631#undef LUAI_MAXSTACK
641#define LUAI_MAXSTACK 15000 632#define LUAI_MAXSTACK 15000
642 633