Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
3a0defdf4This file is pinned to the selected release. Download the original to open it in your design tool.
//
// scanf.c
// test
//
// Created by crinq on 05.12.13.
// Copyright (c) 2013 Rene Hopf. All rights reserved.
//
#include "scanf.h"
int sscanf_(const char *buf, const char *format, ...){
int ret = 0;
va_list arg;
va_start(arg, format);
ret = vfsscanf_(buf, format, arg);
va_end(arg);
return(ret);
}
int isBinDigit(char c){
return(c == '0' || c == '1');
}
int isChar(char c){
return((c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a') || isDecDigit(c));
}
int isNameChar(char c){
return(isChar(c) || c == '_' || c == '-' || c == '.');
}
int isDecDigit(char c){
return(c >= '0' && c <= '9');
}
int isHexDigit(char c){
return((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));
}
int isWhitespace(char c){
return(c == ' ' || c == '\t');
}
int vfsscanf_(const char *buf, const char *format, va_list arg){
int buffer_pos = 0;
int format_pos = 0;
int string_pos = 0;
int ret = 0;
int found = 0;
int *i;
float *f;
char *c;
int invert;
float tf;
int state = 0; // 0 = last char = normal char
// 1 = last char = '%'
// 2 = last char = '\'
while(format[format_pos]){
found = 0;
switch(state){
case 0:
switch(format[format_pos]){
case '%':
state = 1;
format_pos++;
continue;
break;
case '\'':
state = 2;
format_pos++;
continue;
break;
case ' ': // parse whithespaces
while(isWhitespace(buf[buffer_pos])){
buffer_pos++;
found++;
}
found++;
break;
default:
if(format[format_pos] != buf[buffer_pos++]){
return(ret);
}
found++;
}
break;
case 1:
switch(format[format_pos]){
case '%':
if(buf[buffer_pos++] != '%'){
return(ret);
}
found++;
break;
case 'c':
c = va_arg(arg, char *);
*c = buf[buffer_pos++];
found++;
break;
case 's':
string_pos = 0;
c = va_arg(arg, char *);
//while(isChar(buf[buffer_pos])){
while(!isWhitespace(buf[buffer_pos])){
c[string_pos] = buf[buffer_pos++];
string_pos++;
c[string_pos] = '\0';
found++;
}
break;
case 'N':
string_pos = 0;
c = va_arg(arg, char *);
//while(isChar(buf[buffer_pos])){
while(isNameChar(buf[buffer_pos])){
c[string_pos] = buf[buffer_pos++];
string_pos++;
c[string_pos] = '\0';
found++;
}
break;
case 'i':
i = va_arg(arg, int *);
*i = 0;
invert = 1;
if(buf[buffer_pos] == '-'){
invert = -1;
buffer_pos++;
}
else if(buf[buffer_pos] == '+'){
buffer_pos++;
}
while(isDecDigit(buf[buffer_pos])){
*i *= 10;
*i += buf[buffer_pos++] - '0';
found++;
}
*i *= invert;
break;
case 'b':
i = va_arg(arg, int *);
*i = 0;
invert = 1;
if(buf[buffer_pos] == '-'){
invert = -1;
buffer_pos++;
}
else if(buf[buffer_pos] == '+'){
buffer_pos++;
}
if(!(buf[buffer_pos] == 'b' || buf[buffer_pos] == 'B')){
return(ret);
}
buffer_pos++;
while(isBinDigit(buf[buffer_pos])){
*i *= 2;
*i += buf[buffer_pos++] - '0';
found++;
}
*i *= invert;
break;
case 'h':
i = va_arg(arg, int *);
*i = 0;
invert = 1;
if(buf[buffer_pos] == '-'){
invert = -1;
buffer_pos++;
}
else if(buf[buffer_pos] == '+'){
buffer_pos++;
}
if(buf[buffer_pos++] != '0'){
return(ret);
}
if(buf[buffer_pos++] != 'x'){
return(ret);
}
while(isHexDigit(buf[buffer_pos])){
*i *= 16;
if(buf[buffer_pos] < 'A'){
*i += buf[buffer_pos++] - '0';
}
else if(buf[buffer_pos] < 'a'){
*i += buf[buffer_pos++] - 'A' + 10;
}
else{
*i += buf[buffer_pos++] - 'a' + 10;
}
found++;
}
*i *= invert;
break;
case 'f':
f = va_arg(arg, float *);
*f = 0;
tf = 10;
invert = 1;
if(buf[buffer_pos] == '-'){
invert = -1;
buffer_pos++;
}
else if(buf[buffer_pos] == '+'){
buffer_pos++;
}
while(isDecDigit(buf[buffer_pos])){
*f *= 10;
*f += buf[buffer_pos++] - '0';
found++;
}
if(buf[buffer_pos] == '.'){
buffer_pos++;
while(isDecDigit(buf[buffer_pos])){
*f += (buf[buffer_pos++] - '0') / tf;
tf *= 10;
found++;
}
}
*f *= invert;
break;
default:
return(ret);
break;
}
state = 0;
break;
case 2:
switch(format[format_pos]){
case '\'':
if(buf[buffer_pos++] != '\''){
return(ret);
}
found++;
break;
case 'n':
if(buf[buffer_pos++] != '\n'){
return(ret);
}
found++;
break;
default:
return(ret);
break;
}
state = 0;
break;
default:
break;
}
format_pos++;
if(!found){
return(ret);
}
ret++;
}
return(ret);
}