예제 #1
0
int vsscanf(FAR char *buf, FAR const char *fmt, va_list ap)
{
  FAR char       *bufstart;
  FAR char       *tv;
  FAR const char *tc;
  bool            lflag;
  bool            noassign;
  int             count;
  int             width;
  int             base = 10;
  char            tmp[MAXLN];

  lvdbg("vsscanf: buf=\"%s\" fmt=\"%s\"\n", buf, fmt);

  /* Remember the start of the input buffer.  We will need this for %n
   * calculations.
   */

  bufstart = buf;

  /* Parse the format, extracting values from the input buffer as needed */

  count    = 0;
  width    = 0;
  noassign = false;
  lflag    = false;

  while (*fmt && *buf)
    {
      /* Skip over white space */

      while (isspace(*fmt))
        {
          fmt++;
        }

      /* Check for a conversion specifier */

      if (*fmt == '%')
        {
          lvdbg("vsscanf: Specifier found\n");

          /* Check for qualifiers on the conversion specifier */
          fmt++;
          for (; *fmt; fmt++)
            {
              lvdbg("vsscanf: Processing %c\n", *fmt);

              if (strchr("dibouxcsefgn%", *fmt))
                {
                  break;
                }

              if (*fmt == '*')
                {
                  noassign = true;
                }
              else if (*fmt == 'l' || *fmt == 'L')
                {
                  /* NOTE: Missing check for long long ('ll') */

                  lflag = true;
                }
              else if (*fmt >= '1' && *fmt <= '9')
                {
                  for (tc = fmt; isdigit(*fmt); fmt++);
                  strncpy(tmp, tc, fmt - tc);
                  tmp[fmt - tc] = '\0';
                  width = atoi(tmp);
                  fmt--;
                }
            }

          /* Process %s:  String conversion */

          if (*fmt == 's')
            {
              lvdbg("vsscanf: Performing string conversion\n");

              while (isspace(*buf))
                {
                  buf++;
                }

              /* Was a fieldwidth specified? */

              if (!width)
                {
                  /* No... Guess a field width using some heuristics */

                  width = findwidth(buf, fmt);
                }

              if (!noassign)
                {
                  tv = va_arg(ap, char*);
                  strncpy(tv, buf, width);
                  tv[width] = '\0';
                }

              buf += width;
            }
예제 #2
0
파일: lib_sscanf.c 프로젝트: dgvogol/nuttx
int vsscanf(FAR const char *buf, FAR const char *fmt, va_list ap)
{
  FAR const char *bufstart;
  FAR char       *tv;
  FAR const char *tc;
  bool            lflag;
  bool            noassign;
  int             count;
  int             width;
  int             base = 10;
  char            tmp[MAXLN];

  lvdbg("vsscanf: buf=\"%s\" fmt=\"%s\"\n", buf, fmt);

  /* Remember the start of the input buffer.  We will need this for %n
   * calculations.
   */

  bufstart = buf;

  /* Parse the format, extracting values from the input buffer as needed */

  count    = 0;
  width    = 0;
  noassign = false;
  lflag    = false;

  /* Loop until all characters in the fmt string have been processed.  We
   * may have to continue loop after reaching the end the input data in
   * order to handle trailing %n format specifiers.
   */

  while (*fmt)
    {
      /* Skip over white space */

      while (isspace(*fmt))
        {
          fmt++;
        }

      /* Check for a conversion specifier */

      if (*fmt == '%')
        {
          lvdbg("vsscanf: Specifier found\n");

          /* Check for qualifiers on the conversion specifier */

          fmt++;
          for (; *fmt; fmt++)
            {
              lvdbg("vsscanf: Processing %c\n", *fmt);

              if (strchr("dibouxcsefgn%", *fmt))
                {
                  break;
                }

              if (*fmt == '*')
                {
                  noassign = true;
                }
              else if (*fmt == 'l' || *fmt == 'L')
                {
                  /* NOTE: Missing check for long long ('ll') */

                  lflag = true;
                }
              else if (*fmt >= '1' && *fmt <= '9')
                {
                  for (tc = fmt; isdigit(*fmt); fmt++);
                  strncpy(tmp, tc, fmt - tc);
                  tmp[fmt - tc] = '\0';
                  width = atoi(tmp);
                  fmt--;
                }
            }

          /* Process %s:  String conversion */

          if (*fmt == 's')
            {
              lvdbg("vsscanf: Performing string conversion\n");

              /* Get a pointer to the char * value.  We need to do this even
               * if we have reached the end of the input data in order to
               * update the 'ap' variable.
               */

              tv = NULL;      /* To avoid warnings about beign uninitialized */
              if (!noassign)
                {
                  tv    = va_arg(ap, char*);
                  tv[0] = '\0';
                }

              /* But we only perform the data conversion is we still have
               * bytes remaining in the input data stream.
               */

              if (*buf)
                {
                  while (isspace(*buf))
                    {
                      buf++;
                    }

                  /* Was a fieldwidth specified? */

                  if (!width)
                    {
                      /* No... Guess a field width using some heuristics */

                      width = findwidth(buf, fmt);
                    }

                  /* Copy the string (if we are making an assignment) */

                  if (!noassign)
                    {
                      strncpy(tv, buf, width);
                      tv[width] = '\0';
                    }

                  /* Update the buffer pointer past the string in the input */

                  buf += width;
                }
            }