mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2024-12-28 04:23:38 +01:00
stdio: use compact storage for %[] set in scanf
256 bytes of globals is a *lot* on the G-III.
This commit is contained in:
parent
5b85d53826
commit
1caaa8ff63
1 changed files with 31 additions and 38 deletions
|
@ -2,6 +2,7 @@
|
|||
#include "../../stdlib/stdlib_p.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void __scanf_start(struct __scanf_input *in)
|
||||
|
@ -106,50 +107,44 @@ void __scanf_store_d(long double value, int size, va_list *args)
|
|||
// %ms and %m[set] are not implemented (with memory allocation while parsing a chain or a set of characters)
|
||||
|
||||
|
||||
/* list of allowed char given by a set %[], this is updated at every set */
|
||||
bool __asciiallowed[256] = { true };
|
||||
/* Set of bytes allowed in a given set %[]. */
|
||||
static uint8_t bracket_set[32];
|
||||
|
||||
/* unallow all the char for the current set */
|
||||
void __unallow_all_set( void )
|
||||
/* Allow/disallow the entire set */
|
||||
static void bracket_set_init(bool allow)
|
||||
{
|
||||
for(int u =0; u<=255; u++)
|
||||
__asciiallowed[u]=false;
|
||||
memset(bracket_set, allow ? 0xff : 0x00, sizeof bracket_set);
|
||||
}
|
||||
|
||||
/* allow all the char for the current set */
|
||||
void __allow_all_set( void )
|
||||
/* Allow/disallow a range of characters. Both ends are included. */
|
||||
static void bracket_set_range(uint8_t start, uint8_t end, bool allow)
|
||||
{
|
||||
for(int u =0; u<=255; u++)
|
||||
__asciiallowed[u]=true;
|
||||
for(int u = start; u <= end; u++) {
|
||||
int byte = u >> 3;
|
||||
int bit = 1 << (u & 7);
|
||||
if(allow)
|
||||
bracket_set[byte] |= bit;
|
||||
else
|
||||
bracket_set[byte] &= ~bit;
|
||||
}
|
||||
}
|
||||
|
||||
/* allo a range of char for the current set */
|
||||
/* note1 : c1 and c2 do not to be sorted */
|
||||
/* note2 : not sur if C standard requires to be ordered or not */
|
||||
void __define_set_range( char c1, char c2, bool value )
|
||||
/* Check whether a byte is allowed by the bracket set. */
|
||||
static bool bracket_set_test(int c)
|
||||
{
|
||||
char beg = (c1 < c2 ? c1 : c2 );
|
||||
char end = (c1 >= c2 ? c1 : c2 );
|
||||
|
||||
for (int u=beg; u<=end; u++)
|
||||
__asciiallowed[u] = value;
|
||||
int byte = (c >> 3);
|
||||
int bit = 1 << (c & 7);
|
||||
return (c != EOF) && (bracket_set[byte] & bit);
|
||||
}
|
||||
|
||||
/* return true if the char is in the allowed set or false otherwise */
|
||||
bool __is_allowed(int c)
|
||||
{
|
||||
return (c != EOF) && __asciiallowed[c];
|
||||
}
|
||||
|
||||
|
||||
/* return 0 if Ok or -1 if syntax err in the set format */
|
||||
int __scanset(char const * __restrict__ format, int *pos )
|
||||
static int bracket_set_parse(char const * __restrict__ format, int *pos )
|
||||
{
|
||||
int __sor = 0;
|
||||
int __eor = 0;
|
||||
bool __neg = false;
|
||||
|
||||
__unallow_all_set();
|
||||
bracket_set_init(false);
|
||||
|
||||
(*pos)++;
|
||||
|
||||
|
@ -157,11 +152,11 @@ int __scanset(char const * __restrict__ format, int *pos )
|
|||
if (format[*pos] == '^' ) {
|
||||
__neg = true;
|
||||
(*pos)++;
|
||||
__allow_all_set();
|
||||
bracket_set_init(true);
|
||||
|
||||
// the char ']' is part of the set
|
||||
if (format[*pos] == ']' ) {
|
||||
__asciiallowed[ ']' ] = !__neg;
|
||||
bracket_set_range(']', ']', !__neg);
|
||||
(*pos)++;
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +165,7 @@ int __scanset(char const * __restrict__ format, int *pos )
|
|||
__neg = false;
|
||||
// the char ']' is part of the set
|
||||
if (format[*pos] == ']' ) {
|
||||
__asciiallowed[ ']' ] = !__neg;
|
||||
bracket_set_range(']', ']', !__neg);
|
||||
(*pos)++;
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +175,7 @@ int __scanset(char const * __restrict__ format, int *pos )
|
|||
if (format[*pos]=='-') {
|
||||
// the char '-' is included in the allowed set
|
||||
if (format[*pos+1]==']') {
|
||||
__asciiallowed[ '-' ] = !__neg; // if set in very final position before']', this is the char '-' only
|
||||
bracket_set_range('-', '-', !__neg);
|
||||
(*pos)++;
|
||||
// we have now finished the reading of the set cause the following char is ']'
|
||||
return 0;
|
||||
|
@ -189,7 +184,7 @@ int __scanset(char const * __restrict__ format, int *pos )
|
|||
else {
|
||||
(*pos)++;
|
||||
__eor = format[*pos];
|
||||
__define_set_range( __sor, __eor, !__neg );
|
||||
bracket_set_range( __sor, __eor, !__neg );
|
||||
}
|
||||
}
|
||||
// we find the char ']' so it means we reach the end of this set
|
||||
|
@ -199,7 +194,7 @@ int __scanset(char const * __restrict__ format, int *pos )
|
|||
// we are considering one particular char and prepare for a potential range if we find the char '-' later on
|
||||
else {
|
||||
__sor = format[*pos];
|
||||
__asciiallowed[ __sor ] = !__neg;
|
||||
bracket_set_range(__sor, __sor, !__neg);
|
||||
(*pos)++;
|
||||
}
|
||||
}
|
||||
|
@ -232,8 +227,6 @@ int __scanf(
|
|||
MOD = sizeof(int);
|
||||
skip = false;
|
||||
|
||||
__allow_all_set();
|
||||
|
||||
if( format[pos] == ' ' ) {
|
||||
__purge_space(in);
|
||||
}
|
||||
|
@ -251,14 +244,14 @@ int __scanf(
|
|||
switch(format[pos]) {
|
||||
// we need to decrypt the corresponding scanf set of character
|
||||
case '[': {
|
||||
err = __scanset( format, &pos );
|
||||
err = bracket_set_parse( format, &pos );
|
||||
if (err!=0) return validrets;
|
||||
int currentlength = 0;
|
||||
// we need to assign the read char to the corresponding pointer
|
||||
char *c = skip ? NULL : va_arg(*args, char *);
|
||||
for(int u=0; u<readmaxlength; u++) {
|
||||
int temp = __scanf_peek(in);
|
||||
if(__is_allowed(temp)) {
|
||||
if(bracket_set_test(temp)) {
|
||||
__scanf_in(in);
|
||||
if(c) *c++ = temp;
|
||||
currentlength++;
|
||||
|
|
Loading…
Reference in a new issue