forked from len0rd/rockbox
Lua replace fscanf
Rocklua was using the full fscanf implementation to simply read %ld for the file:read("*n") function wasting 1k on unneeded/unused functionality Instead, I've implemented a filetol function to duplicate it without the extra overhead using strtol which as an added bonus ERANGE errors now resolve to LONG_MIN and LONGMAX instead of integer overflow filetol() reads long int from an open file, skips preceding whitespaces returns -1 if error, 1 on success. *num set to LONG_MAX or LONG_MIN on overflow. If number of digits is > than LUAI_MAXNUMBER2STR filepointer will continue till the next non digit but buffer will stop being filled with characters. Preceding zero is ignored. Change-Id: Ia42d0f73c63a894625bca4581e9b7e1cc7387fd2
This commit is contained in:
parent
cc0a4c632a
commit
eab73b3dee
6 changed files with 66 additions and 295 deletions
|
@ -8,6 +8,7 @@
|
|||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2008 Dan Everton (safetydan)
|
||||
* Copyright (C) 2018 William Wilgus
|
||||
* String function implementations taken from dietlibc 0.31 (GPLv2 License)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -24,6 +25,8 @@
|
|||
#define _ROCKCONF_H_ /* Protect against unwanted include */
|
||||
#include "lua.h"
|
||||
|
||||
extern long strtol(const char *nptr, char **endptr, int base);
|
||||
|
||||
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
|
||||
int errno = 0;
|
||||
#endif
|
||||
|
@ -101,3 +104,63 @@ int get_current_path(lua_State *L, int level)
|
|||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* filetol()
|
||||
reads long int from an open file, skips preceding
|
||||
whitespaces returns -1 if error, 1 on success.
|
||||
*num set to LONG_MAX or LONG_MIN on overflow.
|
||||
If number of digits is > than LUAI_MAXNUMBER2STR
|
||||
filepointer will continue till the next non digit
|
||||
but buffer will stop being filled with characters.
|
||||
Preceding zero is ignored
|
||||
*/
|
||||
int filetol(int fd, long *num)
|
||||
{
|
||||
static char buffer[LUAI_MAXNUMBER2STR];
|
||||
int retn = -1;
|
||||
char chbuf = 0;
|
||||
size_t count = 0;
|
||||
bool neg = false;
|
||||
long val;
|
||||
|
||||
while (rb->read(fd, &chbuf, 1) == 1)
|
||||
{
|
||||
if(!isspace(chbuf) || retn == 1)
|
||||
{
|
||||
if(chbuf == '0') /* strip preceeding zeros */
|
||||
{
|
||||
*num = 0;
|
||||
retn = 1;
|
||||
}
|
||||
else if(chbuf == '-' && retn != 1)
|
||||
neg = true;
|
||||
else
|
||||
{
|
||||
rb->lseek(fd, -1, SEEK_CUR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (rb->read(fd, &chbuf, 1) == 1)
|
||||
{
|
||||
if(!isdigit(chbuf))
|
||||
{
|
||||
rb->lseek(fd, -1, SEEK_CUR);
|
||||
break;
|
||||
}
|
||||
else if (count < LUAI_MAXNUMBER2STR - 2)
|
||||
buffer[count++] = chbuf;
|
||||
}
|
||||
|
||||
if(count)
|
||||
{
|
||||
buffer[count] = '\0';
|
||||
val = strtol(buffer, NULL, 10);
|
||||
*num = (neg)? -val:val;
|
||||
retn = 1;
|
||||
}
|
||||
|
||||
return retn;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue