From eab73b3deead4054ba8a1d9165b577ad935b9a05 Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Mon, 29 Oct 2018 02:54:35 -0400 Subject: 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 --- apps/plugins/lua/rockaux.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'apps/plugins/lua/rockaux.c') diff --git a/apps/plugins/lua/rockaux.c b/apps/plugins/lua/rockaux.c index ba3a37343b..562d1654a7 100644 --- a/apps/plugins/lua/rockaux.c +++ b/apps/plugins/lua/rockaux.c @@ -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; +} + -- cgit v1.2.3