Logo Search packages:      
Sourcecode: ksh version File versions

fmtfmt.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                  David Korn <dgk@research.att.com>                   *
*                   Phong Vo <kpv@research.att.com>                    *
*                                                                      *
***********************************************************************/
#pragma prototyped

/*
 * Glenn Fowler
 * AT&T Research
 *
 * return printf(3) format signature given format string
 * the format signature contains one char per format optionally preceded
 * by the number of `*' args
 *    c     char
 *    d     double
 *    D     long double
 *    f     float
 *    h     short
 *    i     int
 *    j     long long
 *    l     long
 *    p     void*
 *    s     string
 *    t     ptrdiff_t
 *    z     size_t
 *    ?     unknown
 */

#include <ast.h>
#include <ctype.h>

char*
fmtfmt(const char* as)
{
      register char*    s = (char*)as;
      char*       buf;
      int         i;
      int         c;
      int         a;
      int         q;
      int         x;
      int         t;
      int         m;
      int         n;
      int         z;
      char        formats[256];
      unsigned int      extra[elementsof(formats)];

      z = 1;
      i = m = 0;
      for (;;)
      {
            switch (*s++)
            {
            case 0:
                  break;
            case '%':
                  if (*s == '%')
                        continue;
                  n = 0;
                  a = 0;
                  q = 0;
                  t = '?';
                  x = 0;
                  for (;;)
                  {
                        switch (c = *s++)
                        {
                        case 0:
                              s--;
                              break;
                        case '(':
                              q++;
                              continue;
                        case ')':
                              if (--q <= 0)
                                    n = 0;
                              continue;
                        case '0': case '1': case '2': case '3':
                        case '4': case '5': case '6': case '7':
                        case '8': case '9':
                              n = n * 10 + (c - '0');
                              continue;
                        case '$':
                              a = n;
                              n = 0;
                              continue;
                        case '*':
                              x++;
                              n = 0;
                              continue;
                        case 'h':
                              if (!q)
                                    t = t == 'h' ? 'c' : 'h';
                              continue;
                        case 'l':
                              if (!q)
                                    t = t == 'l' ? 'j' : 'l';
                              continue;
                        case 'j':
                        case 't':
                        case 'z':
                              if (!q)
                                    t = c;
                              continue;
                        case 'c':
                        case 'p':
                        case 's':
                              if (!q)
                              {
                                    t = c;
                                    break;
                              }
                              continue;
                        case 'e':
                        case 'g':
                              if (!q)
                              {
                                    switch (t)
                                    {
                                    case 'j':
                                          t = 'D';
                                          break;
                                    default:
                                          t = 'd';
                                          break;
                                    }
                                    break;
                              }
                              continue;
                        case 'f':
                              if (!q)
                              {
                                    switch (t)
                                    {
                                    case 'j':
                                          t = 'D';
                                          break;
                                    case 'l':
                                          t = 'd';
                                          break;
                                    default:
                                          t = c;
                                          break;
                                    }
                                    break;
                              }
                              continue;
                        default:
                              if (!q && isalpha(c))
                              {
                                    if (t == '?')
                                          t = 'i';
                                    break;
                              }
                              n = 0;
                              continue;
                        }
                        break;
                  }
                  if (a)
                        i = a;
                  else
                        i++;
                  if (i < elementsof(formats))
                  {
                        formats[i] = t;
                        if (extra[i] = x)
                              do z++; while (x /= 10);
                        if (m < i)
                              m = i;
                  }
                  continue;
            default:
                  continue;
            }
            break;
      }
      s = buf = fmtbuf(m + z);
      for (i = 1; i <= m; i++)
      {
            if (extra[i])
                  s += sfsprintf(s, 10, "%d", extra[m]);
            *s++ = formats[i];
      }
      *s = 0;
      return buf;
}

Generated by  Doxygen 1.6.0   Back to index