Logo Search packages:      
Sourcecode: ksh version File versions

nocomment.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1987-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>                  *
*                                                                      *
***********************************************************************/
#pragma prototyped

/*
 * Glenn Fowler
 * AT&T Research
 *
 * nocomment -- strip C comments
 */

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

#if 0
static int line_sfputc(int line, Sfio_t* sp, int c)
{
      sfprintf(sp, "<<<C:%d>>>", line);
      return sfputc(sp, c);
}
static int line_sfputr(int line, Sfio_t* sp, const char* buf, int op)
{
      sfprintf(sp, "<<<R:%d>>>", line);
      return sfputr(sp, buf, op);
}
#undef      sfputc
#define sfputc(a,b)     line_sfputc(__LINE__,a,b)
#undef      sfputr
#define sfputr(a,b,c)   line_sfputr(__LINE__,a,b,c)
#endif

#define SYNC()    do                                        \
            {                                         \
                  if (line > prev && line > directive)            \
                  {                                   \
                        if (sfsprintf(buf, sizeof(buf), "\n#%s %d\n", sync <= 0 ? "line" : "", line + 1) <= line - prev)      \
                        {                             \
                              sfputr(op, buf, -1);          \
                              prev = line;                  \
                        }                             \
                        else while (prev < line)            \
                        {                             \
                              prev++;                       \
                              sfputc(op, '\n');       \
                        }                             \
                        data = 0;                     \
                  }                                   \
            } while (0)

#define DATA(c)   do                                        \
            {                                         \
                  SYNC();                                   \
                  data = 1;                           \
                  sfputc(op, c);                            \
            } while (0)

/*
 * get next token on ip
 */

static char*
token(register Sfio_t* ip)
{
      register int      c;
      register char*    s;

      static char buf[1024];

      s = buf;
      for (;;)
      {
            switch (c = sfgetc(ip))
            {
            case EOF:
                  if (s > buf)
                        break;
                  return 0;
            case '\\':
            case '/':
            case '\n':
                  sfungetc(ip, c);
                  break;
            default:
                  if (isspace(c))
                  {
                        if (s > buf)
                        {
                              sfungetc(ip, c);
                              break;
                        }
                  }
                  else if (s < &buf[sizeof(buf)-1])
                        *s++ = c;
                  continue;
            }
            break;
      }
      *s = 0;
      return buf;
}

/*
 * uncomment ip into op
 */

off_t
nocomment(register Sfio_t* ip, Sfio_t* op)
{
      register int      c = 0;
      register int      p;
      register int      data = 0;
      int         sync = 0;
      int         formals = 0;
      unsigned long     line = 0;
      unsigned long     prev = 0;
      unsigned long     directive = 0;
      Sfio_t*           pp = 0;
      off_t       count;
      int         quote;
      int         n;
      char*       s;
      char        buf[PATH_MAX];

      count = sftell(op);
      for (;;)
      {
      next:
            p = c;
            c = sfgetc(ip);
      check:
            switch (c)
            {
            case EOF:
                  if (line != prev)
                        sfputc(op, '\n');
                  goto done;
            case 0:
                  sfputc(op, c);
                  sfmove(ip, op, SF_UNBOUND, -1);
                  goto done;
            case '\\':
                  DATA(c);
                  switch (c = sfgetc(ip))
                  {
                  case EOF:
                        goto done;
                  case '\n':
                        directive++;
                        prev = ++line;
                        sfputc(op, c);
                        c = 0;
                        break;
                  default:
                        sfputc(op, c);
                        break;
                  }
                  break;
            case '\f':
            case '\t':
            case '\v':
                  c = ' ';
                  /*FALLTHROUGH*/
            case ' ':
                  if (data) switch (p)
                  {
                  case ' ':
                  case '\n':
                  case '(':
                  case '[':
                  case ']':
                  case '{':
                  case '}':
                  case ';':
                  case ':':
                  case '!':
                  case '<':
                  case '>':
                  case '|':
                  case ',':
                  case '?':
                  case '*':
                        break;
                  case ')':
                        if (directive == line && formals)
                        {
                              formals = 0;
                              sfputc(op, ' ');
                        }
                        break;
                  default:
                        switch (c = sfgetc(ip))
                        {
                        case '\n':
                        case ')':
                        case '[':
                        case ']':
                        case '{':
                        case '}':
                        case ';':
                        case ':':
                        case '=':
                        case '!':
                        case '<':
                        case '>':
                        case '|':
                        case ',':
                        case '?':
                              break;
                        case '(':
                              if (directive == line && formals)
                              {
                                    formals = 0;
                                    sfputc(op, ' ');
                              }
                              break;
                        case '*':
                              if (p == '/' || p == '=')
                                    sfputc(op, ' ');
                              break;
                        case '+':
                        case '-':
                        case '&':
                              if (p == c || p == '=')
                                    sfputc(op, ' ');
                              break;
                        default:
                              sfputc(op, ' ');
                              break;
                        }
                        p = ' ';
                        goto check;
                  }
                  break;
            case '\n':
                  data = 0;
                  line++;
                  break;
            case '#':
                  SYNC();
                  directive = line;
                  formals = 1;
                  if (sync >= 0 && !data)
                  {
                        if (s = token(ip))
                        {
                              if (isdigit(*s))
                              {
                                    sync = 1;
                                    directive = 0;
                                    line = strtol(s, NiL, 10);
                                    if (s = sfgetr(ip, '\n', 1))
                                    {
                                          while (isspace(*s))
                                                s++;
                                          if (*s == '"')
                                          {
                                                sfprintf(op, "# %d %s\n", line, s);
                                                prev = line;
                                          }
                                    }
                                    break;
                              }
                              if (!sync)
                              {
                                    if (!pp && line <= 24 && streq(s, "pragma"))
                                    {
                                          if ((s = token(ip)) && streq(s, "prototyped"))
                                          {
                                                sync = -1;
                                                if (c = sffileno(ip))
                                                {
                                                      n = dup(0);
                                                      close(0);
                                                      dup(c);
                                                }
                                                sfseek(ip, (Sfoff_t)(-1), SEEK_CUR);
                                                sfsync(ip);
                                                if (pp = sfpopen(NiL, "proto -fns", "r"))
                                                      ip = pp;
                                                if (c)
                                                {
                                                      close(0);
                                                      dup(n);
                                                }
                                                c = 0;
                                                break;
                                          }
                                          DATA('#');
                                          sfputr(op, "pragma", ' ');
                                          sfputr(op, s, -1);
                                          c = 0;
                                          break;
                                    }
                                    if (!streq(s, "ident") && !streq(s, "line") && !streq(s, "pragma"))
                                          sync = -1;
                              }
                              DATA('#');
                              sfputr(op, s, -1);
                              c = 0;
                        }
                        else sync = -1;
                  }
                  if (c) DATA(c);
                  else data = 1;
                  break;
            case '/':
                  switch (c = sfgetc(ip))
                  {
                  case EOF:
                        goto done;
                  case '/':
                        for (;;) switch (p = c, c = sfgetc(ip))
                        {
                        case EOF:
                              goto done;
                        case '\n':
                              if (p == '\\')
                              {
                                    sfputc(op, p);
                                    sfputc(op, c);
                                    prev = ++line;
                                    break;
                              }
                              p = ' ';
                              c = '\n';
                              goto check;
                        }
                        break;
                  case '*':
                        for (;;) switch (p = c, c = sfgetc(ip))
                        {
                        case EOF:
                              goto done;
                        case '\n':
                              directive++;
                              line++;
                              break;
                        case '*':
                              for (;;)
                              {
                                    switch (c = sfgetc(ip))
                                    {
                                    case EOF:
                                          goto done;
                                    case '\n':
                                          directive++;
                                          line++;
                                          break;
                                    case '/':
                                          p = c = ' ';
                                          goto check;
                                    case '*':
                                          continue;
                                    }
                                    break;
                              }
                              break;
                        }
                        break;
                  default:
                        p = '/';
                        DATA(p);
                        goto check;
                  }
                  break;
            case '"':
            case '\'':
                  DATA(c);
                  quote = c;
                  for (;;)
                  {
                        switch (c = sfgetc(ip))
                        {
                        case EOF:
                              goto done;
                        case '\\':
                              sfputc(op, c);
                              switch (c = sfgetc(ip))
                              {
                              case EOF:
                                    goto done;
                              case '\n':
                                    directive++;
                                    prev = ++line;
                                    break;
                              }
                              break;
                        case '"':
                        case '\'':
                              if (c == quote)
                              {
                                    sfputc(op, c);
                                    goto next;
                              }
                              break;
                        case '\n':
                              p = ' ';
                              goto check;
                        }
                        sfputc(op, c);
                  }
                  break;
            default:
                  DATA(c);
                  break;
            }
      }
 done:
      count = count < 0 ? 0 : (sferror(ip) || sferror(op)) ? -1 : (sftell(op) - count);
      if (pp) sfclose(pp);
      return count;
}

Generated by  Doxygen 1.6.0   Back to index