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 19 of file sscanf.c.

References _lucid_vsscanf().

Referenced by addr_from_str().

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


Generated on Tue Jun 19 20:38:45 2007 for lucid by  doxygen 1.5.2