Logo Search packages:      
Sourcecode: ksh version File versions  Download package

convert.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1984-2007 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                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
 *
 * convert single char edit ops to long form
 */

static const char id[] = "\n@(#)$Id: make-convert (AT&T Research) 1995-12-25 $\0\n";

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

#include "expand.h"

#define EXBUF           1024
#define DELETE          ((char*)0)
#define KEEP            ((char*)sfstdout)
#define RE_ALL          (1<<0)
#define RE_LOWER  (1<<1)
#define RE_UPPER  (1<<2)

static struct Convstate_s
{
      int         delimiter;
      int         function;
      const char* longflag;
      Edit_map_t**      map;
} state;

static char*      expand(char*, char*);

static char*
editcontext(register char* beg, register char* cur)
{
      register char*    s;

      static char buf[EXBUF];

      s = strcopy(buf, ">>>");
      strncpy(s, beg, cur - beg);
      s += strlen(s);
      strcpy(s, "<<<");
      return(buf);
}

#define DEL (del==':'?state.delimiter:del)

static char*
expandops(register char* xp, register char* ed, int del)
{
      register int                  c;
      register char*                s;
      register int                  op;
      register const Edit_map_t*    mp;
      register const Edit_opt_t*    fp;
      const Edit_map_t*       zp;
      Edit_map_t* const*            mpp;
      char*                   dir;
      char*                   bas;
      char*                   suf;
      char*                   val;
      char*                   oldp;
      char*                   newp;
      char*                   eb;
      char*                   dp;
      char*                   vp;
      const Edit_xxx_t*       bp;
      int                     glob;
      int                     cnt;
      int                     cntlim;
      int                     qual;
      int                     n;
      int                     m;
      int                     e;
      int                     sep;
      int                     arg;
      int                     aux;
      char                    buf[EXBUF];
      char                    tmp[16];

      int                     bound = 0;
      int                     delimited = 0;

      expand(buf, ed);
      ed = buf;
      dir = bas = suf = DELETE;
      eb = ed;
      debug((-5, "expandops(`%s')", ed));
      op = 0;
      for (;;)
      {
            if (op != 'T') bound = 0;
            for (bp = editxxx; bp->old; bp++)
                  if (strneq(bp->old, ed, bp->len))
                  {
                        strncpy(ed, bp->xxx, bp->len);
                        break;
                  }
            if (!(op = *ed++)) break;
            if (op == del) continue;
            switch (op)
            {
            case '@':
            case 'V':
                  sep = 1;
                  switch (op)
                  {
                  case '@':
                        sep = 0;
                        val = "join";
                        break;
                  case 'V':
                        val = "literal";
                        switch (*ed)
                        {
                        case 'A':
                              ed++;
                              val = "auxilliary";
                              break;
                        case 'P':
                              ed++;
                              val = "primary";
                              break;
                        }
                        break;
                  }
                  *xp++ = ' ';
                  if (!delimited)
                  {
                        delimited = 1;
                        if (del != ':')
                              *xp++ = '`';
                  }
                  *xp++ = DEL;
                  *xp++ = ' ';
                  xp = strcopy(xp, val);
                  if (!sep)
                        delimited = -1;
                  continue;
            }
            sep = EQ;

            /*
             * collect the operands
             */

            if (op == 'C' || op == '/' || op == 'Y' || op == '?')
            {
                  /*
                   * substitute: <delim><old><delim><new><delim>[g]
                   * conditional: <delim><non-null><delim><null><delim>
                   */

                  val = ed;
                  n = op;
                  switch (op)
                  {
                  case 'C':
                  case 'Y':
                        if (n = *ed) ed++;
                        break;
                  case '/':
                        op = 'C';
                        val--;
                        break;
                  case '?':
                        op = 'Y';
                        val--;
                        break;
                  }
                  oldp = ed;
                  for (cnt = 0; c = *ed; ed++)
                  {
                        if (c == '(') cnt++;
                        else if (c == ')' && !--n) cnt = 0;
                        else if (cnt <= 0)
                        {
                              if (c == n)
                              {
                                    ed++;
                                    break;
                              }
                              if (c == '\\' && !*++ed)
                                    error(3, "unterminated lhs of %s: %s", op == 'C' ? "substitution" : "conditional", editcontext(eb, ed));
                        }
                  }
                  newp = ed;
                  for (cnt = 0; c = *ed; ed++)
                  {
                        if (c == '(') cnt++;
                        else if (c == ')' && !--n) cnt = 0;
                        else if (cnt <= 0)
                        {
                              if (c == n)
                              {
                                    ed++;
                                    break;
                              }
                              if (c == '\\' && !*++ed)
                                    error(3, "unterminated rhs of %s: %s", op == 'C' ? "substitution" : "conditional", editcontext(eb, ed));
                        }
                  }
                  glob = 0;
                  while (*ed && *ed != del) switch (*ed++)
                  {
                  case 'G':
                        *(ed - 1) = 'g';
                        /*FALLTHROUGH*/
                  case 'g':
                        glob |= RE_ALL;
                        break;
                  case 'L':
                        *(ed - 1) = 'l';
                        /*FALLTHROUGH*/
                  case 'l':
                        glob |= RE_LOWER;
                        break;
                  case 'O':
                        *(ed - 1) = 'o';
                        /*FALLTHROUGH*/
                  case 'o':
                        glob |= RE_ALL;
                        break;
                  case 'U':
                        *(ed - 1) = 'u';
                        /*FALLTHROUGH*/
                  case 'u':
                        glob |= RE_UPPER;
                        break;
                  default:
                        error(1, "invalid character `%c' after %s", *(ed - 1), op == 'C' ? "substitution" : "conditional");
                        break;
                  }
                  s = ed;
                  if (*ed) ed++;
                  *s = 0;
            }
            else if (*ed == del)
            {
                  ed++;
                  val = KEEP;
            }
            else if (*ed)
            {
                  /*
                   * value: [!<>=][=][<val>]
                   */

                  if (op != '$') switch (*ed++)
                  {
                  case '!':
                        if (*ed == '=')
                        {
                              ed++;
                              sep = NE;
                        }
                        else sep = NOT;
                        break;
                  case '=':
                        if (*ed == '=') ed++;
                        sep = EQ;
                        break;
                  case '<':
                        if (*ed == '=')
                        {
                              ed++;
                              sep = LE;
                        }
                        else if (*ed == '>')
                        {
                              ed++;
                              sep = NE;
                        }
                        else sep = LT;
                        break;
                  case '>':
                        if (*ed == '=')
                        {
                              ed++;
                              sep = GE;
                        }
                        else sep = GT;
                        break;
                  default:
                        error(3, "edit operator delimiter omitted: %s", editcontext(eb, ed));
                        break;
                  }
                  val = ed;
                  for (cnt = n = 0; c = *ed; ed++)
                  {
                        if (cnt)
                        {
                              if (c == cnt) n++;
                              else if (c == cntlim && !--n) cnt = 0;
                        }
                        else if (c == '(')
                        {
                              cnt = '(';
                              cntlim = ')';
                              n++;
                        }
                        else if (c == '[')
                        {
                              cnt = '[';
                              cntlim = ']';
                              n++;
                        }
                        else if (c == del && n <= 0)
                        {
                              *ed++ = 0;
                              break;
                        }
                  }
                  if (!*val) val = DELETE;
            }
            else val = KEEP;
            dp = xp;
            *xp++ = ' ';
            if (!delimited)
            {
                  delimited = 1;
                  if (del != ':')
                        *xp++ = '`';
            }
            if (delimited < 0)
                  delimited = 1;
            else
            {
                  *xp++ = DEL;
                  *xp++ = ' ';
            }

            /*
             * B, D and S are grouped before application
             */

            switch (op)
            {
            case '$':
                  val--;
                  xp = strcopy(xp, val);
                  error(1, "%s: expand result may need conversion too", val);
                  continue;
            case 'B':
            case 'D':
            case 'S':
                  switch (op)
                  {
                  case 'B':
                        bas = val;
                        break;
                  case 'D':
                        dir = val;
                        break;
                  case 'S':
                        suf = val;
                        break;
                  }
                  switch (*ed)
                  {
                  case 'B':
                        if (bas == DELETE)
                        {
                              xp = dp;
                              continue;
                        }
                        break;
                  case 'D':
                        if (dir == DELETE)
                        {
                              xp = dp;
                              continue;
                        }
                        break;
                  case 'S':
                        if (suf == DELETE)
                        {
                              xp = dp;
                              continue;
                        }
                        break;
                  }
                  sep = 0;
                  if (dir == DELETE)
                  {
                        xp = strcopy(xp, "nodirectory");
                        sep = 1;
                  }
                  else
                  {
                        if (dir != KEEP)
                        {
                              xp += sfsprintf(xp, EXBUF, "directory %s", dir);
                              sep = 1;
                        }
                        dir = DELETE;
                  }
                  if (bas == DELETE)
                  {
                        if (sep)
                        {
                              *xp++ = ' ';
                              *xp++ = DEL;
                              *xp++ = ' ';
                        }
                        else sep = 1;
                        xp = strcopy(xp, "nobase");
                  }
                  else
                  {
                        if (bas != KEEP)
                        {
                              if (sep)
                              {
                                    *xp++ = ' ';
                                    *xp++ = DEL;
                                    *xp++ = ' ';
                              }
                              else sep = 1;
                              xp += sfsprintf(xp, EXBUF, "base %s", bas);
                        }
                        bas = DELETE;
                  }
                  if (suf == DELETE)
                  {
                        if (sep)
                        {
                              *xp++ = ' ';
                              *xp++ = DEL;
                              *xp++ = ' ';
                        }
                        else sep = 1;
                        xp = strcopy(xp, "nosuffix");
                  }
                  else
                  {
                        if (suf != KEEP)
                        {
                              if (sep)
                              {
                                    *xp++ = ' ';
                                    *xp++ = DEL;
                                    *xp++ = ' ';
                              }
                              else sep = 1;
                              xp += sfsprintf(xp, EXBUF, "suffix %s", suf);
                        }
                        suf = DELETE;
                  }
                  break;
            default:
                  qual = 0;
                  if (op == 'T')
                  {
                        for (;; val++)
                        {
                              switch (*val)
                              {
                              case 'R':
                                    xp += sfsprintf(xp, EXBUF, "time %srule", state.longflag);
                                    op = 0;
                                    break;
                              case 'W':
                                    qual |= ED_NOWAIT;
                                    continue;
                              case 'X':
                                    qual |= ED_NOBIND;
                                    continue;
                              }
                              break;
                        }
                        if (*val == 'S' && *(val + 1) == 'F')
                        {
                              qual |= ED_FORCE;
                              sfsprintf(tmp, sizeof(tmp), "S%s", val + 2);
                              val = tmp;
                        }
                  }
                  if (sep == NE)
                        xp = strcopy(xp, "! ");
                  if (!op) break;
                  if (val == DELETE || val == KEEP)
                  {
                        val = "";
                        arg = 0;
                        aux = 0;
                  }
                  else
                  {
                        arg = val[0];
                        aux = val[1];
                  }
                  vp = val;
                  zp = 0;
                  for (mpp = state.map; mpp < &state.map[elementsof(editmap)]; mpp++)
                  {
                        mp = *mpp;
                        if (mp->cmd.type != ED_QUAL)
                        {
                              if (mp->cmd.op != op)
                              {
                                    if (!(fp = mp->options))
                                          continue;
                                    for (; fp->name; fp++)
                                          if (fp->cmd.type == ED_OP && fp->cmd.op == op)

                                                break;
                                    if (!fp->name)
                                          continue;
                              }
                              m = 0;
                              switch (mp->cmd.arg)
                              {
                              case 0:
                                    if (!zp || zp->options && !mp->options)
                                          zp = mp;
                                    if (arg && !mp->options)
                                          continue;
                                    break;
                              case '<':
                                    if (!(sep & LT))
                                          continue;
                                    break;
                              case '>':
                                    if (!(sep & GT))
                                          continue;
                                    break;
                              case '*':
                                    if (arg)
                                    {
                                          if (arg != 'F' && arg != '*')
                                                continue;
                                          val++;
                                    }
                                    break;
                              default:
                                    if (arg != mp->cmd.arg)
                                          continue;
                                    if (mp->cmd.aux)
                                    {
                                          if (aux != mp->cmd.aux)
                                                continue;
                                          if (!mp->options)
                                          {
                                                if (arg && *val)
                                                      val++;
                                                if (*val)
                                                      val++;
                                          }
                                    }
                                    else if (arg)
                                    {
                                          m = 1;
                                          if (*val)
                                                val++;
                                    }
                                    break;
                              }
                              dp = xp;
                              if (op == 'T')
                              {
                                    if (bound) bound = 0;
                                    else if (!(qual & ED_NOBIND))
                                    {
                                          bound = 1;
                                          xp = strcopy(xp, "bind");
                                          if (qual & ED_NOWAIT)
                                                xp += sfsprintf(xp, EXBUF, " %snowait", state.longflag);
                                          if (streq(mp->name, "bind"))
                                                break;
                                          xp += sfsprintf(xp, EXBUF, " %c ", DEL);
                                    }
                              }
                              xp = strcopy(xp, mp->name);
                              if (qual & ED_FORCE)
                                    xp += sfsprintf(xp, EXBUF, " %sforce", state.longflag);
                              if (fp = mp->options)
                              {
                                    n = sep;
                                    for (e = 0; fp->name; fp++)
                                    {
                                          if (!*fp->name && fp->cmd.type == ED_QUAL)
                                                sep ^= fp->cmd.op;
                                          else if (fp->cmd.type == ED_QUAL && (sep & fp->cmd.op) || fp->cmd.type == ED_OP && (fp->cmd.op && op == fp->cmd.op || !fp->cmd.op && arg == fp->cmd.arg && (!fp->cmd.aux || aux == fp->cmd.aux)))
                                          {
                                                if (!*fp->name)
                                                      e = 1;
                                                else
                                                {
                                                      if (!m) m = 1;
                                                      if (m > 0 && fp->cmd.type == ED_OP)
                                                      {
                                                            m = -1;
                                                            val++;
                                                            if (fp->cmd.aux)
                                                                  val++;
                                                      }
                                                      *xp++ = ' ';
                                                      xp = strcopy(xp, state.longflag);
                                                      xp = strcopy(xp, fp->name);
                                                }
                                          }
                                    }
                                    if (!m)
                                    {
                                          if (e)
                                          {
                                                if (*val) val++;
                                          }
                                          else if (!aux || isupper(aux))
                                          {
                                                if (!zp) zp = mp;
                                                sep = n;
                                                xp = dp;
                                                val = vp;
                                                continue;
                                          }
                                    }
                              }
                              if (aux == '=' && *val == '=')
                                    val++;
                              if (*val)
                              {
                                    *xp++ = ' ';
                                    if (*val == '-')
                                    {
                                          *xp++ = '-';
                                          *xp++ = '-';
                                          *xp++ = ' ';
                                    }
                                    if (op != 'P' || arg != 'P')
                                          xp = strcopy(xp, val);
                                    else
                                    {
                                          while (c = *val++)
                                                *xp++ = c == ',' ? ' ' : c;
                                          *xp = 0;
                                    }
                              }
                              break;
                        }
                  }
                  if (mpp >= &state.map[elementsof(editmap)])
                  {
                        if (zp)
                        {
                              xp = strcopy(xp, zp->name);
                              if (*val)
                              {
                                    *xp++ = ' ';
                                    xp = strcopy(xp, val);
                              }
                        }
                        else
                        {
                              error(2, "%c: operator not matched", op);
                              xp = strcopy(xp, ">>>HUH<<<");
                        }
                  }
                  break;
            }
      }
      *xp = 0;
      return(xp);
}

/*
 * expand var name into xp
 */

static char*
expandvar(register char* xp, register char* v)
{
      register int      c;
      register char*    s;

      switch (c = *v++)
      {
      case 0:
            break;
      case '$':
      case '"':
            return(expand(xp, v - 1));
      case '-':
      case '+':
            xp = strcopy(xp, "option ");
            if (c == '+')
                  xp += sfsprintf(xp, EXBUF, "%sset ", state.longflag);
            xp = expand(xp, v);
            break;
      case '=':
            xp = strcopy(xp, "makeargs");
            break;
      case '#':
            s = "argc";
            goto internal;
      case ';':
            s = "data";
            goto internal;
      case '<':
            s = "target";
            goto internal;
      case '>':
            s = "prereqs new";
            goto internal;
      case '*':
            s = "prereqs";
            goto internal;
      case '~':
            s = "prereqs all";
            goto internal;
      case '@':
            s = "action";
            goto internal;
      case '%':
            s = state.function ? "args" : "stem";
            goto internal;
      case '!':
            s = "prereqs implicit";
            goto internal;
      case '&':
            s = "prereqs implicit state";
            goto internal;
      case '?':
            s = "prereqs all implicit";
            goto internal;
      case '^':
            s = "target original";
            goto internal;
      internal:
            while (*v == c)
            {
                  v++;
                  xp = strcopy(xp, "parent ");
            }
            for (;;)
            {
                  switch (*xp++ = *s++)
                  {
                  case 0:
                        xp--;
                        break;
                  case ' ':
                        xp = strcopy(xp, state.longflag);
                        continue;
                  default:
                        continue;
                  }
                  break;
            }
            if (*v)
            {
                  *xp++ = ' ';
                  xp = expand(xp, v);
            }
            break;
      case '.':
            if (v[0] != '.' || v[1] != '.')
                  goto normal;
            xp = strcopy(xp, "rules");
            break;
      default:
            if (!isalnum(c))
                  error(2, "%s: unknown internal variable", v - 1);
            /*FALLTHROUGH*/
      case '_':
      case '(':
      normal:
            xp = expand(xp, v - 1);
            break;
      }
      *xp = 0;
      return(xp);
}

/*
 * expand `$(...)' from a into xp
 */

static char*
expand(register char* xp, register char* a)
{
      register int      c;
      register char*    s;
      int         del;
      int         p;
      int         q;
      char*       ed;
      char*       var;
      char*       vp;

      char        varbuf[EXBUF];

      debug((-4, "expand(`%s')", a));
      if (!(s = strchr(a, '$')))
            return(strcopy(xp, a));
      strncpy(xp, a, s - a);
      xp += s - a;
      a = s;
      while (*a)
      {
            if (*a != '$') *xp++ = *a++;
            else if (*++a == '(')
            {
                  *xp++ = '$';
                  *xp++ = '(';
                  if (isspace(*++a))
                        *xp++ = *a++;
                  else
                  {
                        var = a;
                        ed = 0;
                        vp = 0;
                        del = ':';
                        q = 0;
                        p = 1;
                        while (c = *a++)
                        {
                              if (c == '"') q = !q;
                              else if (q) /* quoted */;
                              else if (c == '(') p++;
                              else if (c == ')')
                              {
                                    if (!--p) break;
                              }
                              else if (!ed && p == 1)
                              {
                                    if (c == '|')
                                    {
                                          *(a - 1) = 0;
                                          if (!vp) vp = varbuf;
                                          else *vp++ = ' ';
                                          vp = expandvar(vp, var);
                                          var = a;
                                          *(a - 1) = c;
                                          c = 0;
                                    }
                                    else if (c == del)
                                    {
                                          c = 0;
                                          ed = a - 1;
                                    }
                                    else if (c == '`')
                                    {
                                          c = 0;
                                          ed = a - 1;
                                          if (!(del = *a++))
                                          {
                                                ed--;
                                                break;
                                          }
                                    }
                              }
                        }
                        if (q || !c)
                        {
                              a--;
                              error(1, "missing %c in %s variable expansion", q ? '"' : ')', s);
                        }
                        if (vp)
                        {
                              xp += sfsprintf(xp, EXBUF, "value ");
                              if (*var == '"')
                              {
                                    c = *(a - 1);
                                    *(a - 1) = 0;
                                    xp += sfsprintf(xp, EXBUF, "%sdefault=%s ", state.longflag, var);
                                    *(a - 1) = c;
                                    var = 0;
                              }
                        }
                        if (ed && *(ed + 1) == 'V')
                        {
                              *ed = 0;
                              if (!vp) xp += sfsprintf(xp, EXBUF, "value ");
                              xp = strcopy(xp, state.longflag);
                              switch (*(ed + 2))
                              {
                              case 'A':
                                    ed += 3;
                                    xp = strcopy(xp, "auxiliary ");
                                    break;
                              case 'P':
                                    ed += 3;
                                    xp = strcopy(xp, "primary ");
                                    break;
                              default:
                                    ed += 2;
                                    xp = strcopy(xp, "literal ");
                                    break;
                              }
                              if (ed == (a - 1))
                                    ed = 0;
                        }
                        if (ed)
                        {
                              if (var && strneq(var, "\"\":T=R", 6))
                                    xp += sfsprintf(xp, EXBUF, "time %swall", state.longflag);
                              else
                              {
                                    c = *ed;
                                    *ed = 0;
                                    if (vp)
                                    {
                                          xp = strcopy(xp, varbuf);
                                          if (var) *xp++ = ' ';
                                    }
                                    if (var) xp = expandvar(xp, var);
                                    *ed = c;
                                    c = *(a - 1);
                                    *(a - 1) = 0;
                                    xp = expandops(xp, ed + 1, del);
                                    *(a - 1) = c;
                              }
                        }
                        else
                        {
                              c = *(a - 1);
                              *(a - 1) = 0;
                              if (vp)
                              {
                                    xp = strcopy(xp, varbuf);
                                    if (var) *xp++ = ' ';
                              }
                              if (var) xp = expandvar(xp, var);
                              *(a - 1) = c;
                        }
                  }
                  *xp++ = ')';
            }
            else *xp++ = '$';
      }
      *xp = 0;
      return(xp);
}

static int
byop(const char* a, const char* b)
{
      register Edit_map_t*    ap = (Edit_map_t*)a;
      register Edit_map_t*    bp = (Edit_map_t*)b;

      if (ap->cmd.type == ED_QUAL) return(-1);
      if (bp->cmd.type == ED_QUAL) return(1);
      if (ap->cmd.op < bp->cmd.op) return(-1);
      if (ap->cmd.op > bp->cmd.op) return(1);
      if (!ap->cmd.arg) return(1);
      if (!bp->cmd.arg) return(-1);
      if (ap->cmd.arg < bp->cmd.arg) return(-1);
      if (ap->cmd.arg > bp->cmd.arg) return(1);
      if (!ap->cmd.aux) return(1);
      if (!bp->cmd.aux) return(-1);
      if (ap->cmd.aux < bp->cmd.aux) return(-1);
      if (ap->cmd.aux > bp->cmd.aux) return(1);
      return(0);
}

main(int argc, char** argv)
{
      register char*    s;
      register int      c;
      Edit_map_t* mp;
      Edit_map_t**      mpp;
      Sfio_t*           ip;
      char        buf[EXBUF];

      error_info.id = "convert";
      state.delimiter = ':';
      state.longflag = "-o ";
      if (!(state.map = newof(0, Edit_map_t*, elementsof(editmap), 0)))
            error(ERROR_SYSTEM|3, "out of space [editmap sort]");
      mpp = state.map;
      mp = (Edit_map_t*)editmap;
      while (mp < &editmap[elementsof(editmap)])
            *mpp++ = mp++;
      strsort((char**)state.map, elementsof(editmap), byop);
      while (c = optget(argv, "d:[delimiter]o:[longflag]D#[debug-level]")) switch (c)
      {
      case 'd':
            state.delimiter = *opt_info.arg;
            break;
      case 'o':
            state.longflag = opt_info.arg;
            break;
      case 'D':
            error_info.trace = -opt_info.num;
            break;
      case '?':
            error(ERROR_USAGE|4, opt_info.arg);
            break;
      case ':':
            error(2, opt_info.arg);
            break;
      }
      if (error_info.errors)
            error(ERROR_USAGE|4, "%s", optusage(NiL));
      argv += opt_info.index;
      for (;;)
      {
            s = *argv++;
            if (!s || streq(s, "-") || streq(s, "/dev/stdin") || streq(s, "/dev/fd/0"))
                  ip = sfstdin;
            else if (!(ip = sfopen(NiL, s, "r")))
            {
                  error(2, "%s: cannot read", s);
                  continue;
            }
            error_info.file = s;
            error_info.line = 0;
            while (s = sfgetr(ip, '\n', 1))
            {
                  error_info.line++;
                  if (*s && !isspace(*s))
                        state.function = strmatch(s, "*FUNCTION*");
                  expand(buf, s);
                  sfputr(sfstdout, buf, '\n');
            }
            error_info.file = 0;
            error_info.line = 0;
            if (!s) break;
            if (ip != sfstdin) sfclose(ip);
      }
      exit(error_info.errors != 0);
}

Generated by  Doxygen 1.6.0   Back to index