Rev 424 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "global.h"#include <stdarg.h>#include "include/string.h"int isspace(int c){return (c == ' ') || (c == '\t') || (c == '\n');}int isdigit(int c){return (c >= '0') && (c <= '9');}int isxdigit(int c){return ((c >= '0') && (c <= '9'))|| ((c >= 'a') && (c <= 'f')) || ((c >= 'A') && (c <= 'F'));}static int parse_dec(int (*peek)(void *userp),void (*pop)(void *userp),void *userp,long *vp){long v = 0;int n = 0;int minus = 0;char ch;if ((*peek)(userp) == '-'){(*pop)(userp);n++;minus = 1;}ch = (*peek)(userp);if (!isdigit(ch))return -1;do{v = v * 10 + ch - '0';(*pop)(userp);n++;ch = (*peek)(userp);} while (isdigit(ch));*vp = minus ? -v : v;return n;}static int parse_chars(int (*peek)(void *userp),void (*pop)(void *userp),void *userp,char *vp,bool fake){int n = 0;char *pt=vp;while (!isspace((*peek)(userp))){if(fake==false)*(pt++) = (*peek)(userp);n++;(*pop)(userp);}if(fake==false)(*pt)='\0';return n;}static int parse_hex(int (*peek)(void *userp),void (*pop)(void *userp),void *userp,unsigned long *vp){unsigned long v = 0;int n = 0;char ch;ch = (*peek)(userp);if (!isxdigit(ch))return -1;do{if (ch >= 'a')ch = ch - 'a' + 10;else if (ch >= 'A')ch = ch - 'A' + 10;elsech = ch - '0';v = v * 16 + ch;(*pop)(userp);n++;ch = (*peek)(userp);} while (isxdigit(ch));*vp = v;return n;}static int skip_spaces(int (*peek)(void *userp),void (*pop)(void *userp),void *userp){int n = 0;while (isspace((*peek)(userp))) {n++;(*pop)(userp);}return n;}static int scan(int (*peek)(void *userp),void (*pop)(void *userp),void *userp,const char *fmt,va_list ap){char ch;int n = 0;int n_chars = 0;int r;long lval;bool skip=false;unsigned long ulval;while ((ch = *fmt++) != '\0'){bool literal = false;if (ch == '%'){ch = *fmt++;if(ch== '*') /* We should process this, but not store it in an arguement */{ch=*fmt++;skip=true;}else{skip=false;}switch (ch){case 'x':n_chars += skip_spaces(peek, pop, userp);if ((r = parse_hex(peek, pop, userp, &ulval)) >= 0){if(skip==false){*(va_arg(ap, unsigned int *)) = ulval;n++;}n_chars += r;}elsereturn n;break;case 'd':n_chars += skip_spaces(peek, pop, userp);if ((r = parse_dec(peek, pop, userp, &lval)) >= 0){if(skip==false){*(va_arg(ap, int *)) = lval;n++;}n_chars += r;}elsereturn n;break;case 'n':if(skip==false){*(va_arg(ap, int *)) = n_chars;n++;}break;case 'l':n_chars += skip_spaces(peek, pop, userp);ch = *fmt++;switch (ch){case 'x':if ((r = parse_hex(peek, pop, userp, &ulval)) >= 0){if(skip==false){*(va_arg(ap, unsigned long *)) = ulval;n++;}n_chars += r;}elsereturn n;break;case 'd':if ((r = parse_dec(peek, pop, userp, &lval)) >= 0){if(skip==false){*(va_arg(ap, long *)) = lval;n++;}n_chars += r;}elsereturn n;break;case '\0':return n;default:literal = true;break;}break;case 's':n_chars += skip_spaces(peek, pop, userp);n_chars += parse_chars(peek,pop, userp,skip?0:va_arg(ap, char *), skip );if(skip==false){n++;}break;case '\0':return n;default:literal = true;break;}} elseliteral = true;if (literal){n_chars += skip_spaces(peek, pop, userp);if ((*peek)(userp) != ch)continue;else{(*pop)(userp);n_chars++;}}}return n;}static int sspeek(void *userp){return **((char **)userp);}static void sspop(void *userp){(*((char **)userp))++;}int sscanf(const char *s, const char *fmt, ...){int r;va_list ap;const char *p;p = s;va_start(ap, fmt);r = scan(sspeek, sspop, &p, fmt, ap);va_end(ap);return r;}