Formatted input conversion


Detailed Description

The scanf() family of functions scans input according to format as described below. This format may contain conversion specifications; the results from such conversions, if any, are stored in the locations pointed to by the pointer arguments that follow format. Each pointer argument must be of a type that is appropriate for the value returned by the corresponding conversion specification.

If the number of conversion specifications in format exceeds the number of pointer arguments, the results are undefined. If the number of pointer arguments exceeds the number of conversion specifications, then the excess pointer arguments are evaluated, but are otherwise ignored.

The format string consists of a sequence of directives which describe how to process the sequence of input characters. If processing of a directive fails, no further input is read, and scanf() returns. A "failure" can be either of the following: input failure, meaning that input characters were unavailable, or matching failure, meaning that the input was inappropriate (see below).

A directive is one of the following:

Format of the format string

Each conversion specification in format begins with either the character '' followed by:

Conversions

The following type modifier characters can appear in a conversion specification:

The following conversion specifiers are available:


Functions

int _lucid_vsscanf (const char *str, const char *fmt, va_list ap)
 read conversion from string using va_list
int _lucid_sscanf (const char *str, const char *fmt,...)
 read conversion from string using variable number of arguments


Function Documentation

int _lucid_vsscanf ( const char *  str,
const char *  fmt,
va_list  ap 
)

read conversion from string using va_list

Parameters:
[in] str source string
[in] fmt format string
[out] ap variable number of arguments
Returns:
Number of converted arguments
Note:
Every conversion happens in this functions. All other scanf functions are just convenient wrappers.

Definition at line 59 of file vsscanf.c.

References char_isspace, __scanf_t::f, __scanf_t::l, __scanf_t::s, SFL_NOOP, SFL_WIDTH, SFR_CHAR, SFR_INT, SFR_LLONG, SFR_LONG, SFR_MAX, SFR_MIN, SFR_SHORT, SFS_CONV, SFS_EOF, SFS_ERR, SFS_FLAGS, SFS_MOD, SFS_NORMAL, SFS_WIDTH, str_len(), str_toumax(), and __scanf_t::w.

Referenced by _lucid_sscanf().

00060 {
00061         /* keep track of converted arguments */
00062         int converted = 0;
00063         
00064         /* current character in format */
00065         char c;
00066         
00067         /* current conversion data */
00068         __scanf_t f;
00069         
00070         /* arguments */
00071         union {
00072                 /* unsigned argument */
00073                 unsigned long long int u;
00074                 
00075                 /* string argument */
00076                 char *s;
00077         } arg;
00078         
00079         /* base used for integer conversions */
00080         int base;
00081         
00082         /* number of bytes converted in str_toumax */
00083         int len;
00084         
00085         /* pointer for string conversion */
00086         char *sp;
00087         
00088         /* don't consume original ap */
00089         va_list ap;
00090         va_copy(ap, _ap);
00091         
00092         /* initialize conversion data */
00093         f.f = 0;
00094         f.l = SFR_INT;
00095         f.s = SFS_NORMAL;
00096         f.w = str_len(str);
00097         
00098         while ((c = *fmt++)) {
00099                 switch (f.s) {
00100                 case SFS_NORMAL:
00101                         if (c == '%') {
00102                                 f.f = 0;
00103                                 f.l = SFR_INT;
00104                                 f.s = SFS_FLAGS;
00105                                 f.w = str_len(str);
00106                         }
00107                         
00108                         else if (char_isspace(c))
00109                                 while (char_isspace(*str))
00110                                         str++;
00111                         
00112                         else if (*str == c)
00113                                 str++;
00114                         
00115                         else
00116                                 f.s = SFS_ERR;
00117                         
00118                         break;
00119                 
00120                 case SFS_FLAGS:
00121                         switch (c) {
00122                         case '*':
00123                                 f.f |= SFL_NOOP;
00124                                 break;
00125                         
00126                         case '0':
00127                         case '1':
00128                         case '2':
00129                         case '3':
00130                         case '4':
00131                         case '5':
00132                         case '6':
00133                         case '7':
00134                         case '8':
00135                         case '9':
00136                                 f.w  = (c - '0');
00137                                 f.f |= SFL_WIDTH;
00138                                 f.s  = SFS_WIDTH;
00139                                 break;
00140                         
00141                         default:
00142                                 f.s = SFS_MOD;
00143                                 fmt--;
00144                                 break;
00145                         }
00146                         
00147                         break;
00148                 
00149                 case SFS_WIDTH:
00150                         if (c >= '0' && c <= '9')
00151                                 f.w = f.w * 10  + (c - '0');
00152                         
00153                         else {
00154                                 f.s = SFS_MOD;
00155                                 fmt--;
00156                         }
00157                         
00158                         break;
00159                 
00160                 case SFS_MOD:
00161                         switch (c) {
00162                         case 'h':
00163                                 f.l--;
00164                                 break;
00165                         
00166                         case 'l':
00167                                 f.l++;
00168                                 break;
00169                         
00170                         default:
00171                                 f.s = SFS_CONV;
00172                                 fmt--;
00173                                 break;
00174                         }
00175                         
00176                         break;
00177                 
00178                 case SFS_CONV:
00179                         f.s = SFS_NORMAL;
00180                         
00181                         if (f.l > SFR_MAX)
00182                                 f.l = SFR_MAX;
00183                         
00184                         if (f.l < SFR_MIN)
00185                                 f.l = SFR_MIN;
00186                         
00187                         switch (c) {
00188                         case 'd':
00189                                 base = 10;
00190                                 goto scan_int;
00191                         
00192                         case 'i': /* signed conversion */
00193                                 base = 0;
00194                                 goto scan_int;
00195                         
00196                         case 'o':
00197                                 base = 8;
00198                                 goto scan_int;
00199                         
00200                         case 'u':
00201                                 base = 10;
00202                                 goto scan_int;
00203                         
00204                         case 'X':
00205                         case 'x':
00206                                 base = 16;
00207                                 goto scan_int;
00208                         
00209                         scan_int:
00210                                 while (char_isspace(*str))
00211                                         str++;
00212                                 
00213                                 if (!*str) {
00214                                         f.s = SFS_EOF;
00215                                         break;
00216                                 }
00217                                 
00218                                 len = str_toumax(str, &arg.u, base, f.w);
00219                                 
00220                                 if (len <= 0) {
00221                                         f.s = SFS_ERR;
00222                                         break;
00223                                 }
00224                                 
00225                                 str += len;
00226                                 converted++;
00227                                 
00228                                 if (!(f.f & SFL_NOOP)) {
00229                                         switch (f.l) {
00230                                         case SFR_CHAR:
00231                                                 *va_arg(ap, unsigned char *) = arg.u;
00232                                                 break;
00233                                         
00234                                         case SFR_SHORT:
00235                                                 *va_arg(ap, unsigned short int *) = arg.u;
00236                                                 break;
00237                                         
00238                                         case SFR_INT:
00239                                                 *va_arg(ap, unsigned int *) = arg.u;
00240                                                 break;
00241                                         
00242                                         case SFR_LONG:
00243                                                 *va_arg(ap, unsigned long int *) = arg.u;
00244                                                 break;
00245                                         
00246                                         case SFR_LLONG:
00247                                                 *va_arg(ap, unsigned long long int *) = arg.u;
00248                                                 break;
00249                                         
00250                                         default:
00251                                                 *va_arg(ap, unsigned long long int *) = arg.u;
00252                                                 break;
00253                                         }
00254                                 }
00255                                 
00256                                 break;
00257                         
00258                         case 'c': /* character conversion */
00259                                 /* default width = 1 */
00260                                 f.w = (f.f & SFL_WIDTH) ? f.w : 1;
00261                                 
00262                                 if ((f.f & SFL_NOOP)) {
00263                                         while (f.w--) {
00264                                                 if (!*str) {
00265                                                         f.s = SFS_EOF;
00266                                                         break;
00267                                                 }
00268                                                 
00269                                                 str++;
00270                                         }
00271                                 }
00272                                 
00273                                 else {
00274                                         arg.s = va_arg(ap, char *);
00275                                         
00276                                         while (f.w--) {
00277                                                 if (!*str) {
00278                                                         f.s = SFS_EOF;
00279                                                         break;
00280                                                 }
00281                                                 
00282                                                 *arg.s++ = *str++;
00283                                         }
00284                                 }
00285                                 
00286                                 if (f.s != SFS_EOF && !(f.f & SFL_NOOP))
00287                                         converted++;
00288                                 
00289                                 break;
00290                         
00291                         case 's': /* string conversion */
00292                                 if (!(f.f & SFL_NOOP)) {
00293                                         while (f.w-- && !char_isspace(*str)) {
00294                                                 if (!*str) {
00295                                                         f.s = SFS_EOF;
00296                                                         break;
00297                                                 }
00298                                                 
00299                                                 str++;
00300                                         }
00301                                 }
00302                                 
00303                                 else {
00304                                         sp = arg.s = va_arg(ap, char *);
00305                                         
00306                                         while (f.w-- && !char_isspace(*str)) {
00307                                                 if (!*str) {
00308                                                         f.s = SFS_EOF;
00309                                                         break;
00310                                                 }
00311                                                 
00312                                                 *sp++ = *str++;
00313                                         }
00314                                         
00315                                         if (f.s != SFS_EOF)
00316                                                 *sp = '\0';
00317                                 }
00318                                 
00319                                 if (f.s != SFS_EOF && !(f.f & SFL_NOOP))
00320                                         converted++;
00321                                 
00322                                 break;
00323                         
00324                         case 'P':
00325                         case 'p': /* pointer conversion */
00326                                 while (char_isspace(*str))
00327                                         str++;
00328                                 
00329                                 if (!*str) {
00330                                         f.s = SFS_EOF;
00331                                         break;
00332                                 }
00333                                 
00334                                 len = str_toumax(str, &arg.u, 0, f.w);
00335                                 
00336                                 if (len <= 0) {
00337                                         f.s = SFS_ERR;
00338                                         break;
00339                                 }
00340                                 
00341                                 if (!(f.f & SFL_NOOP))
00342                                         *va_arg(ap, void **) = (void *) (unsigned long int) arg.u;
00343                                 
00344                                 str += len;
00345                                 converted++;
00346                                 
00347                                 break;
00348                         
00349                         case 'n':
00350                                 *va_arg(ap, int *) = converted;
00351                                 
00352                                 break;
00353                         
00354                         case '%':
00355                                 if (*str == '%')
00356                                         str++;
00357                                 else
00358                                         f.s = SFS_ERR;
00359                                 
00360                                 break;
00361                         
00362                         default:
00363                                 f.s = SFS_ERR;
00364                                 break;
00365                         }
00366                         
00367                         break;
00368                         
00369                 case SFS_EOF:
00370                         converted = converted ? converted : -1;
00371                         
00372                 case SFS_ERR:
00373                         va_end(ap);
00374                         return converted;
00375                 }
00376         }
00377         
00378         if (f.s == SFS_EOF)
00379                 converted = converted ? converted : -1;
00380         
00381         va_end(ap);
00382         return converted;
00383 }

int _lucid_sscanf ( const char *  str,
const char *  fmt,
  ... 
)

read conversion from string using variable number of arguments

Parameters:
[in] str source string
[in] fmt format string
[out] ... variable number of arguments
Returns:
Number of converted arguments

Definition at line 20 of file sscanf.c.

References _lucid_vsscanf().

Referenced by addr_from_str().

00021 {
00022         va_list ap;
00023         va_start(ap, fmt);
00024         
00025         return _lucid_vsscanf(str, fmt, ap);
00026 }


Generated on Sun Dec 3 17:46:16 2006 for lucid by  doxygen 1.5.1