fxlibc/include/fxlibc/scanf.h

80 lines
1.8 KiB
C

#ifndef __SCANF_H__
# define __SCANF_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdbool.h>
/*
** General utilities for scanf(); we expose them here as we use subfunctions of
** strto*() from <stdlib.h> to implement numerical specifiers.
*/
/*
** Input for scanf; exactly one of str and fp must be non-NULL. We include a
** single-character buffer for convenience for scanning functions to test the
** next character, which can be flushed back by ungetc().
*/
struct __scanf_input {
char const * __restrict__ str;
FILE *fp;
// max char to read from the input stream as per user length modifier
int readmaxlength;
int currentlength;
// total number of char read so far in the current call of a XYscanf() function (to return a %n when required)
int readsofar;
int buffer;
};
/* Generic formatted scaning. */
extern int __scanf(
struct __scanf_input * __restrict__ __in,
char const * __restrict__ __format,
va_list *__args);
/* Initialize the input by feeding the buffer byte. */
void __scanf_start(struct __scanf_input *__in);
/* Fetch the next byte from the input and return it (don't call directly). */
int __scanf_fetch(struct __scanf_input *__in);
/* Read the next byte while maintaining the buffer. */
static inline int __scanf_in(struct __scanf_input *__in)
{
int c = __in->buffer;
__in->buffer = __scanf_fetch(__in);
__in->readsofar++;
__in->currentlength++;
return c;
}
/* Peek the next byte without advancing. */
static inline int __scanf_peek(struct __scanf_input *__in)
{
if (__in->readmaxlength==-1 || __in->currentlength<__in->readmaxlength )
return __in->buffer;
else return 0;
}
/* Close the input by unsending the buffer once finished. */
void __scanf_end(struct __scanf_input *__in);
#ifdef __cplusplus
}
#endif
#endif /* __SCANF_H__ */