int opt_vscanf (Opt o, const char *fmt, va_list ap) { ListIterator itr; char *item; int ret = 0; NP_ASSERT (o->magic == OPT_MAGIC); if (!(itr = list_iterator_create (o->list))) msg_exit ("out of memory"); while ((item = list_next (itr))) { va_list vacpy; va_copy (vacpy, ap); ret = vsscanf (item, fmt, vacpy); va_end (vacpy); if (ret > 0) break; } list_iterator_destroy (itr); return ret; }
int direct_vsscanf( const char *str, const char *format, va_list args ) { return vsscanf( str, format, args ); }
static int c_vsscanf(const char *str, const char *format, va_list ap) { return vsscanf(str,format,ap); }
int optstr_get(const char *options, const char *name, const char *fmt, ...) { va_list ap; /* points to each unnamed arg in turn */ int num_args = 0, n = 0; size_t pos, fmt_len = strlen(fmt); const char *ch = NULL; #ifndef HAVE_VSSCANF void *temp[ARG_MAXIMUM]; #endif ch = optstr_lookup(options, name); if (!ch) { return -1; } /* name IS in options */ /* Find how many arguments we expect */ for (pos = 0; pos < fmt_len; pos++) { if (fmt[pos] == '%') { ++num_args; /* is this one quoted with '%%' */ if (pos + 1 < fmt_len && fmt[pos + 1] == '%') { --num_args; ++pos; } } } #ifndef HAVE_VSSCANF if (num_args > ARG_MAXIMUM) { fprintf (stderr, "(%s:%d) Internal Overflow; redefine ARG_MAXIMUM (%d) to something higher\n", __FILE__, __LINE__, ARG_MAXIMUM); return -2; } #endif n = num_args; /* Bool argument */ if (num_args <= 0) { return 0; } /* skip the `=' (if it is one) */ ch += strlen( name ); if( *ch == '=' ) ch++; if( !*ch ) return 0; va_start(ap, fmt); #ifndef HAVE_VSSCANF while (--n >= 0) { temp[num_args - n - 1] = va_arg(ap, void *); } n = sscanf(ch, fmt, temp[0], temp[1], temp[2], temp[3]); #else /* this would be very nice instead of the above, * but it does not seem portable */ n = vsscanf(ch, fmt, ap); #endif va_end(ap); return n; }
This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. */ #include <stdio.h> #include <stdarg.h> #ifndef REGTEST int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... ) { int rc; va_list ap; va_start( ap, format ); rc = vsscanf( s, format, ap ); va_end( ap ); return rc; } #endif #ifdef TEST #define _PDCLIB_FILEID "stdio/sscanf.c" #define _PDCLIB_STRINGIO #include <_PDCLIB_test.h> #define testscanf( s, format, ... ) sscanf( s, format, __VA_ARGS__ ) int main()
int platform_vsscanf(const char *str, const char *format, va_list arg) { return vsscanf(str, format, arg); }
/******************************************************************************* * an alternative to the standard scanf library function: * - this function use fgets to read the line and vsscanf to convert it * - the given input line has to match the format list * - the routine does not stop until the requred input is given * ATTENTION * if ISOC89 is set only %d, %g %e %f and %s is supported by this function *******************************************************************************/ int check_scanf(char *fmt, ...) { char buffer[NDM_BUF_SZ]; char *f = fmt; char *cdum; int got_it = 0; int no_fmt_spec = 0; va_list args; va_start(args, fmt); /*-------------------------------------------------------------------------- | count the number of conversion items in the format string --------------------------------------------------------------------------*/ while ((f = strstr(f, "%")) != NULL) { f += 2; no_fmt_spec++; } /*-------------------------------------------------------------------------- | read the line until the input is correct and complete, | the ISOC99 function vsscanf is used if the ISOC99 extensions are available --------------------------------------------------------------------------*/ #ifdef __USE_ISOC99 while (!got_it) { cdum = fgets(buffer, NDM_BUF_SZ - 1, stdin); if (vsscanf(buffer, fmt, args) == no_fmt_spec) got_it++; else ndm_msg("\nWrong or incomplete input, retry: "); } #else /*-------------------------------------------------------------------------- | read the line until the input is correct and complete, | the ISOC99 function vsscanf is replaced by a rough implementation | with reduced functionality --------------------------------------------------------------------------*/ while (!got_it) { char tok_buf[NDM_BUF_SZ]; char tok_fmt[NDM_BUF_SZ]; char *s, *t; int no_read = 0; int i; /*---------------------------------------------------------------------- | read the line and cut leading blanks and the first % in format ----------------------------------------------------------------------*/ fgets(buffer, NDM_BUF_SZ - 1, stdin); s = buffer; s += strspn(s, " "); t = fmt; t += strspn(t, " "); t = strbftok(t, tok_fmt, NDM_BUF_SZ, "%"); /*---------------------------------------------------------------------- | convert all string using sscanf ----------------------------------------------------------------------*/ for (i = 0; i < no_fmt_spec; i++) { s = strbftok(s, tok_buf, NDM_BUF_SZ, " ,"); t = strbftok(t, tok_fmt, NDM_BUF_SZ, "%"); if (strpbrk(tok_fmt, "d")) no_read += sscanf(tok_buf, "%d", va_arg(args, int *)); else if (strpbrk(tok_fmt, "fge")) no_read += sscanf(tok_buf, "%lf", va_arg(args, double *)); else if (strpbrk(tok_fmt, "s")) no_read += sscanf(tok_buf, "%s", va_arg(args, char *)); }
int String_Format_From(var self, int pos, const char* fmt, va_list va) { StringData* s = cast(self, String); return vsscanf(s->value + pos, fmt, va); }
#include <stdio.h> #include <stdarg.h> #include "libc.h" int sscanf(const char *restrict s, const char *restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vsscanf(s, fmt, ap); va_end(ap); return ret; } #if __GNUC__ >= 9 weak_alias(sscanf,__isoc99_sscanf) __attribute__((nothrow)); #else weak_alias(sscanf,__isoc99_sscanf); #endif
int StrReader::read_fmt(const char *fmt, va_list ap) { if (pos >= size) { bad = 1; return 0; } return vsscanf(pc+pos,fmt,ap); }
int vsscanf_l(const char* str, locale_t l, const char* fmt, va_list args) { return vsscanf(str, fmt, args); }
bool ATCmdParser::vrecv(const char *response, va_list args) { restart: _aborted = false; // Iterate through each line in the expected response while (response[0]) { // Since response is const, we need to copy it into our buffer to // add the line's null terminator and clobber value-matches with asterisks. // // We just use the beginning of the buffer to avoid unnecessary allocations. int i = 0; int offset = 0; bool whole_line_wanted = false; while (response[i]) { if (response[i] == '%' && response[i+1] != '%' && response[i+1] != '*') { _buffer[offset++] = '%'; _buffer[offset++] = '*'; i++; } else { _buffer[offset++] = response[i++]; // Find linebreaks, taking care not to be fooled if they're in a %[^\n] conversion specification if (response[i - 1] == '\n' && !(i >= 3 && response[i-3] == '[' && response[i-2] == '^')) { whole_line_wanted = true; break; } } } // Scanf has very poor support for catching errors // fortunately, we can abuse the %n specifier to determine // if the entire string was matched. _buffer[offset++] = '%'; _buffer[offset++] = 'n'; _buffer[offset++] = 0; debug_if(_dbg_on, "AT? %s\n", _buffer); // To workaround scanf's lack of error reporting, we actually // make two passes. One checks the validity with the modified // format string that only stores the matched characters (%n). // The other reads in the actual matched values. // // We keep trying the match until we succeed or some other error // derails us. int j = 0; while (true) { // Receive next character int c = getc(); if (c < 0) { debug_if(_dbg_on, "AT(Timeout)\n"); return false; } // Simplify newlines (borrowed from retarget.cpp) if ((c == CR && _in_prev != LF) || (c == LF && _in_prev != CR)) { _in_prev = c; c = '\n'; } else if ((c == CR && _in_prev == LF) || (c == LF && _in_prev == CR)) { _in_prev = c; // onto next character continue; } else { _in_prev = c; } _buffer[offset + j++] = c; _buffer[offset + j] = 0; // Check for oob data for (struct oob *oob = _oobs; oob; oob = oob->next) { if ((unsigned)j == oob->len && memcmp( oob->prefix, _buffer+offset, oob->len) == 0) { debug_if(_dbg_on, "AT! %s\n", oob->prefix); oob->cb(); if (_aborted) { debug_if(_dbg_on, "AT(Aborted)\n"); return false; } // oob may have corrupted non-reentrant buffer, // so we need to set it up again goto restart; } } // Check for match int count = -1; if (whole_line_wanted && c != '\n') { // Don't attempt scanning until we get delimiter if they included it in format // This allows recv("Foo: %s\n") to work, and not match with just the first character of a string // (scanf does not itself match whitespace in its format string, so \n is not significant to it) } else { sscanf(_buffer+offset, _buffer, &count); } // We only succeed if all characters in the response are matched if (count == j) { debug_if(_dbg_on, "AT= %s\n", _buffer+offset); // Reuse the front end of the buffer memcpy(_buffer, response, i); _buffer[i] = 0; // Store the found results vsscanf(_buffer+offset, _buffer, args); // Jump to next line and continue parsing response += i; break; } // Clear the buffer when we hit a newline or ran out of space // running out of space usually means we ran into binary data if (c == '\n' || j+1 >= _buffer_size - offset) { debug_if(_dbg_on, "AT< %s", _buffer+offset); j = 0; } } } return true; }
int dSscanf(const char *buffer, const char *format, ...) { va_list args; va_start(args, format); return vsscanf(buffer, format, args); }
__FBSDID("$FreeBSD$"); #include <stdio.h> #include <string.h> #include <stdarg.h> #include <xlocale.h> #include "local.h" int sscanf(const char * __restrict str, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vsscanf(str, fmt, ap); va_end(ap); return (ret); } int sscanf_l(const char * __restrict str, locale_t locale, char const * __restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); ret = vsscanf_l(str, locale, fmt, ap); va_end(ap); return (ret); }
extern int _stdvsscanf(char* s, const char* fmt, va_list args) { return vsscanf(s, fmt, args); }
static bool at_vrecv(const char *response, va_list args) { char *_buffer = at._buffer; char *_recv_delimiter = at._recv_delimiter; char c; int ret = 0; vrecv_start: while (response[0]) { int i = 0; int offset = 0; while (response[i]) { if (memcmp(&response[i + 1 - at._recv_delim_size], _recv_delimiter, at._recv_delim_size) == 0) { i++; break; } else if (response[i] == '%' && response[i + 1] != '%' && response[i + 1] != '*') { _buffer[offset++] = '%'; _buffer[offset++] = '*'; i++; } else { _buffer[offset++] = response[i++]; } } _buffer[offset++] = '%'; _buffer[offset++] = 'n'; _buffer[offset++] = 0; int j = 0; while (true) { ret = at_getc(&c); if (ret != 0) { return false; } _buffer[offset + j++] = c; _buffer[offset + j] = 0; for (int k = 0; k < at._oobs_num; k++) { oob_t *oob = &(at._oobs[k]); if (j == oob->len && memcmp(oob->prefix, at._buffer + offset, oob->len) == 0) { LOGD(MODULE_NAME, "AT! %s\r\n", oob->prefix); oob->cb(oob->arg); goto vrecv_start; } } int count = -1; sscanf(_buffer + offset, _buffer, &count); if (count == j) { LOGD(MODULE_NAME, "AT= %s\r\n", _buffer + offset); memcpy(_buffer, response, i); _buffer[i] = 0; vsscanf(_buffer + offset, _buffer, args); response += i; break; } if (j + 1 >= BUFFER_SIZE - offset || strcmp(&_buffer[offset + j - at._recv_delim_size], _recv_delimiter) == 0) { LOGD(MODULE_NAME, "AT< %s", _buffer + offset); j = 0; } } } return true; }
int sscanf ( /* SYNOPSIS */ const char *str, const char *format, ...) /* FUNCTION Scan the specified string and convert it into the arguments as specified by format. INPUTS str - The routine examines this string. format - Format string. See scanf() for a description ... - Arguments for the result RESULT The number of converted parameters. NOTES EXAMPLE BUGS SEE ALSO fscanf(), vscanf(), vfscanf(), vsscanf() INTERNALS ******************************************************************************/ /* int _sscanf(char * str, const char * format, ... ) */ { #if 1 int retval; va_list args; va_start(args, format); retval = vsscanf(str, format, args); va_end(args); return retval; #else #define TRUE 1 #define FALSE 0 int n = 0; /* Counter of the number of processed letters in the input string s */ char * s_end; char * s = str; char * format_end; long int result; #ifndef AROS_NOFPU double D_result; #endif int maxwidth; int base; int size; int assignment; int retval = 0; va_list arg; va_start(arg, format); /* process the format string as long as there is a character */ while (*format) { /* search for the first letter in the format string that is not a space */ while ( isspace(*format) ) format++; /* see if there is a command */ if ('%' == *format) { /* Examine the next char */ format++; /* Initialize some variables */ maxwidth = -1; base = 10; size = 4; /* The next char can be a '*' */ if ('*' == *format) { /* No assignment to variable */ assignment = FALSE; /* Advance to next character */ format++; } else { assignment = TRUE; } /* Next there can be a number, a letter h,l or L or a * */ switch (*format) { case 'h' : size = sizeof(short int); format++; break; case 'l' : size = sizeof(long int); format++; break; case 'L' : size = sizeof(long double); format++; break; } /* now let us see for the format letter */ switch (*format++) { case 'd' : /* let us look for a signed integer number in the string */ result = strtol(s, &s_end, 10); n += (s_end - s); s = s_end; /* Ptr to the rest of the string in s */ if (TRUE == assignment) { retval++; if (sizeof(short int) == size) *va_arg(arg, short int *) = result; else *va_arg(arg, long int *) = result; } break; case 'i' : /* let us look for a signed integer number that can have a different base, i.e. hex or octal. Here we have to examine the next few letters in the format string for the base */ base = strtol(format, &format_end, 10); format = format_end; result = strtol(s, &s_end, base); n += (s_end - s); s = s_end; /* Ptr to the rest of the string in s */ if (TRUE == assignment) { retval++; if (sizeof(short int) == size) *va_arg(arg, short int *) = result; else *va_arg(arg, long int *) = result; } break; case 'o' : /* let us read in a signed octal number */ base = 8; result = strtol(s, &s_end, base); n += (s_end - s); s = s_end; /* Ptr to the rest of the string in s */ if (TRUE == assignment) { retval++; if (sizeof(short int) == size) *va_arg(arg, short int *) = result; else *va_arg(arg, long int *) = result; } break; case 'x' : case 'X' : /* let us read in a signed hexadecimal number */ base = 16; result = strtol(s, &s_end, base); n+= (s_end - s); s = s_end; /* Ptr to the rest of the string in s */ if (TRUE == assignment) { retval++; if (sizeof(short int) == size) *va_arg(arg, short int *) = result; else *va_arg(arg, long int *) = result; } break; case 'u' : /* let us read in an unsigned integer */ base = 10; result = strtoul(s, &s_end, base); n += (s_end - s); s = s_end; /* Ptr to the rest of the string in s */ if (TRUE == assignment) { retval++; if (sizeof(short int) == size) *va_arg(arg, short int *) = result; else *va_arg(arg, long int *) = result; } break; case 'c' : /* let us read in one single character */ /* do not skip whitespaces in s */ if (TRUE == assignment) { retval++; *va_arg(arg, char *) = *s++; } n++; break; case 's' : /* let us read in a string until the next whitespace comes along */ /* skip leading whitespaces in s */ while (isspace(*s)) { s++; n++; } /* s points to the start of the string */ s_end = s; /* let us look for the end of the string in s */ while (*s_end && isalpha(*s_end)) { s_end++; n++; } /* s_end points to the end of the string */ if(TRUE == assignment) { char * dest = va_arg(arg, char *); retval++; strncpy(dest, s, (long)s_end-(long)s); *(dest+((long)s_end-(long)s))='\0'; } s = s_end; break; #ifndef AROS_NOFPU case 'e' : case 'E' : case 'f' : case 'g' : case 'G' : /* a real number with optional sign, opt. decimal point and optional exponent */ D_result = strtod(s, &s_end); if (TRUE == assignment) { retval++; *va_arg(arg, double *) = D_result; } n += (long)(s_end - s); s = s_end; break; #endif case 'n' : /* the user wants to know how many letters we already processed on the input (not format!!) string. So we give hime the content of letter variable n */ if (TRUE == assignment) { /* NO retval++; here!! */ *va_arg(arg, long *) = n; } break; default : /* no known letter -> error!! */ return retval; } } /* if */