Logo Search packages:      
Sourcecode: ksh version File versions

dump.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1984-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
 *
 * make dump and trace routines
 */

#include "make.h"

static int        dumpall;    /* don't be selective         */

/*
 * list a rule name in re-readable form
 */

static void
dumpname(register Sfio_t* sp, register Rule_t* r, char* sep)
{
      register char*    s;
      register char*    t;
      register int      paren;
      int         quote;

      if (!dumpall && state.list)
      {
            s = (r->property & P_state) || (r->dynamic & D_alias) ? r->name : unbound(r);
            for (t = s, paren = 0; *t && (paren || !istype(*t, C_TERMINAL)); t++)
                  if (*t == '(')
                        paren++;
                  else if (*t == ')')
                        paren--;
            if (quote = (*t || t == s))
                  sfputc(sp, '"');
            for (; *s; s++)
            {
                  switch (*s)
                  {
                  case '"':
                        if (quote)
                              sfputc(sp, '\\');
                        break;
                  case '$':
                        if (*(s + 1) == '(')
                              sfputc(sp, '$');
                        break;
                  }
                  sfputc(sp, *s);
            }
            if (quote)
                  sfputc(sp, '"');
      }
      else
      {
            if (*r->name)
                  sfputr(sp, r->name, -1);
            else
            {
                  sfputc(sp, '"');
                  sfputc(sp, '"');
            }
            if (!(r->property & P_state) && r->uname)
                  sfprintf(sp, "==%s", r->uname);
      }
#if DEBUG
      if (state.test & 0x00004000)
            sfprintf(sp, "@%p", r);
#endif
      sfputr(sp, sep, -1);
}

/*
 * list a single rule and its attributes
 */

static int
listrule(const char* s, char* v, void* h)
{
      register Rule_t*  r = (Rule_t*)v;
      register List_t*  p;
      register int            n;
      register Sfio_t*  sp = (Sfio_t*)h;

      if (!dumpall && state.list && (r->name != s ||
            !(r->property & (P_accept|P_after|P_always|P_archive|P_before|P_command|P_force|P_foreground|P_functional|P_ignore|P_immediate|P_implicit|P_joint|P_local|P_make|P_multiple|P_operator|P_parameter|P_read|P_repeat|P_target|P_terminal|P_use|P_virtual)) && !((r->property & P_attribute) && r->attribute) && !r->semaphore))
                  return 0;
      sfputc(sp, '\n');
      dumpname(sp, r, " : ");
      if (dumpall || !state.list)
      {
            if ((r->property & P_staterule) && isaltstate(r->name))
                  sfputr(sp, "cancel=", -1);
            sfprintf(sp, "[%s] ", timestr(r->time));
      }
      if (!(r->property & P_attribute))
      {
            if (r->attribute)
                  for (p = internal.attribute->prereqs; p; p = p->next)
                        if (r->attribute & p->rule->attribute)
                              sfputr(sp, p->rule->name, ' ');
            if (r->scan)
                  for (p = internal.scan->prereqs; p; p = p->next)
                        if (p->rule->scan == r->scan)
                        {
                              sfputr(sp, p->rule->name, ' ');
                              break;
                        }
      }
      if (dumpall || !state.list)
      {
            if (r->property & P_state)
            {
                  if (r->property & P_staterule)
                  {
                        if (!isaltstate(r->name))
                              sfprintf(sp, "event=[%s] ", timestr(r->event));
                  }
                  else if (r->property & P_statevar)
                        sfputr(sp, "statevar", ' ');
                  else
                        sfputr(sp, "state", ' ');
            }
            if (r->view > r->preview)
                  sfprintf(sp, "view=%c/%c ", VIEWOFFSET + r->view, VIEWOFFSET + r->preview);
            else if (r->view)
                  sfprintf(sp, "view=%c ", VIEWOFFSET + r->view);
            else if (r->preview && r->preview <= state.maxview)
                  sfprintf(sp, "preview=%c ", VIEWOFFSET + r->preview);
            if (r->action && !*r->action)
                  sfputr(sp, "null", ' ');
            if (r->must)
                  sfprintf(sp, "must=%d ", r->must);
            if (r->semaphore)
                  sfprintf(sp, "semaphore=%d ", r->semaphore - 1);

            if (r->property & P_archive)
                  sfputr(sp, "archive", ' ');
            if (r->property & P_accept)
                  sfputr(sp, "accept", ' ');
            if (r->active)
                  sfputr(sp, "active", ' ');
            if (r->property & P_after)
                  sfputr(sp, "after", ' ');
            if (r->property & P_always)
                  sfputr(sp, "always", ' ');
            if (r->property & P_attribute)
            {
                  if (r->attribute)
                        sfprintf(sp, "attribute=0x%08x ", r->attribute);
                  else if (r->scan)
                        sfprintf(sp, "scan=%d ", r->scan);
                  else
                        sfputr(sp, "attribute", ' ');
            }
            if (r->property & P_before)
                  sfputr(sp, "before", ' ');
            if (r->property & P_command)
                  sfputr(sp, "command", ' ');
            if (r->property & P_dontcare)
                  sfputr(sp, "dontcare", ' ');
            if (r->property & P_force)
                  sfputr(sp, "force", ' ');
            if (r->property & P_foreground)
                  sfputr(sp, "foreground", ' ');
            if (r->property & P_functional)
                  sfputr(sp, "functional", ' ');
            if (r->property & P_ignore)
                  sfputr(sp, "ignore", ' ');
            if (r->property & P_immediate)
                  sfputr(sp, "immediate", ' ');
            if (r->property & P_implicit)
                  sfputr(sp, "implicit", ' ');
            if (r->property & P_internal)
                  sfputr(sp, "internal", ' ');
            if (r->property & P_joint)
                  sfputr(sp, "joint", ' ');
            if (r->property & P_local)
                  sfputr(sp, "local", ' ');
            if (r->property & P_make)
                  sfputr(sp, "make", ' ');
            if (r->property & P_metarule)
                  sfputr(sp, "metarule", ' ');
            if (r->property & P_multiple)
                  sfputr(sp, "multiple", ' ');
            if (r->property & P_operator)
                  sfputr(sp, "operator", ' ');
            if (r->property & P_parameter)
                  sfputr(sp, "parameter", ' ');
            if (r->property & P_read)
                  sfputr(sp, "read", ' ');
            if (r->property & P_readonly)
                  sfputr(sp, "readonly", ' ');
            if (r->property & P_repeat)
                  sfputr(sp, "repeat", ' ');
            if (r->property & P_target)
                  sfputr(sp, "target", ' ');
            if (r->property & P_terminal)
                  sfputr(sp, "terminal", ' ');
            if (r->property & P_use)
                  sfputr(sp, "use", ' ');
            if (r->property & P_virtual)
                  sfputr(sp, "virtual", ' ');

            if (r->dynamic & D_alias)
                  sfputr(sp, "alias", ' ');
            if (r->dynamic & D_aliaschanged)
                  sfputr(sp, "aliaschanged", ' ');
#if BINDINDEX
            if (r->dynamic & D_bindindex)
                  sfputr(sp, "bindindex", ' ');
#endif
            if (r->dynamic & D_built)
                  sfputr(sp, "built", ' ');
            if (r->dynamic & D_cached)
                  sfputr(sp, "cached", ' ');
            if (r->dynamic & D_compiled)
                  sfputr(sp, "compiled", ' ');
            if (r->dynamic & D_context)
                  sfputr(sp, "context", ' ');
            if (r->dynamic & D_dynamic)
                  sfputr(sp, "dynamic", ' ');
            if (r->dynamic & D_entries)
                  sfputr(sp, "entries", ' ');
            if (r->dynamic & D_garbage)
                  sfputr(sp, "garbage", ' ');
            if (r->dynamic & D_global)
                  sfputr(sp, "global", ' ');
            if (r->dynamic & D_hasafter)
                  sfputr(sp, "hasafter", ' ');
            if (r->dynamic & D_hasbefore)
                  sfputr(sp, "hasbefore", ' ');
            if (r->dynamic & D_hasmake)
                  sfputr(sp, "hasmake", ' ');
            if (r->dynamic & D_hasscope)
                  sfputr(sp, "hasscope", ' ');
            if (r->dynamic & D_hassemaphore)
                  sfputr(sp, "hassemaphore", ' ');
            if (r->dynamic & D_index)
                  sfputr(sp, "index", ' ');
            if (r->dynamic & D_intermediate)
                  sfputr(sp, "intermediate", ' ');
            if (r->dynamic & D_lower)
                  sfputr(sp, "lower", ' ');
            if (r->dynamic & D_lowres)
                  sfputr(sp, "lowres", ' ');
            if (r->dynamic & D_member)
                  sfputr(sp, "member", ' ');
            if (r->dynamic & D_membertoo)
                  sfputr(sp, "membertoo", ' ');
            if (r->dynamic & D_regular)
                  sfputr(sp, "regular", ' ');
            if (r->dynamic & D_same)
                  sfputr(sp, "same", ' ');
            if (r->dynamic & D_scanned)
                  sfputr(sp, "scanned", ' ');
            if (r->dynamic & D_scope)
                  sfputr(sp, "scope", ' ');
            if (r->dynamic & D_select0)
                  sfputr(sp, "select0", ' ');
            if (r->dynamic & D_select1)
                  sfputr(sp, "select1", ' ');
            if (r->dynamic & D_source)
                  sfputr(sp, "source", ' ');
            if (r->dynamic & D_triggered)
                  sfputr(sp, "triggered", ' ');
            if ((r->property & (P_state|P_statevar)) == P_state)
                  sfputr(sp, "state", -1);
            else if (!(r->dynamic & D_bound))
                  sfputr(sp, "unbound", -1);
            else
                  switch (r->status)
                  {
                  case NOTYET:
                        break;
                  case UPDATE:
                        sfputr(sp, "UPDATE", -1);
                        break;
                  case MAKING:
                        sfputr(sp, "MAKING", -1);
                        break;
                  case TOUCH:
                        sfputr(sp, "TOUCH", -1);
                        break;
                  case EXISTS:
                        sfputr(sp, "EXISTS", -1);
                        break;
                  case IGNORE:
                        sfputr(sp, "IGNORE", -1);
                        break;
                  case FAILED:
                        sfputr(sp, "FAILED", -1);
                        break;
                  case OLDRULE:
                        sfputr(sp, "OLDRULE", -1);
                        break;
#if DEBUG
                  default:
                        sfprintf(sp, "STATUS=%d", r->status);
                        break;
#endif
                  }
            if (r->mark)
            {
                  sfputr(sp, " |mark", '|');
                  if (r->mark & M_bind)
                        sfputr(sp, "bind", '|');
                  if (r->mark & M_compile)
                        sfputr(sp, "compile", '|');
                  if (r->mark & M_directory)
                        sfputr(sp, "directory", '|');
                  if (r->mark & M_generate)
                        sfputr(sp, "generate", '|');
                  if (r->mark & M_mark)
                        sfputr(sp, "mark", '|');
                  if (r->mark & M_metarule)
                        sfputr(sp, "metarule", '|');
                  if (r->mark & M_scan)
                        sfputr(sp, "scan", '|');
                  if (r->mark & M_waiting)
                        sfputr(sp, "waiting", '|');
            }
            sfputc(sp, '\n');
      }
      else
      {
            if (r->property & P_accept)
                  sfputr(sp, internal.accept->name, ' ');
            if (r->property & P_after)
                  sfputr(sp, internal.after->name, ' ');
            if (r->property & P_always)
                  sfputr(sp, internal.always->name, ' ');
            if (r->property & P_attribute)
            {
                  if (r->attribute)
                        sfputr(sp, internal.attribute->name, ' ');
                  else if (r->scan)
                        sfputr(sp, internal.scan->name, ' ');
            }
            if (r->property & P_before)
                  sfputr(sp, internal.before->name, ' ');
            if (r->property & P_force)
                  sfputr(sp, internal.force->name, ' ');
            if (r->property & P_foreground)
                  sfputr(sp, internal.foreground->name, ' ');
            if (r->property & P_functional)
                  sfputr(sp, internal.functional->name, ' ');
            if (r->property & P_joint)
                  sfputr(sp, internal.joint->name, ' ');
            if (r->property & P_make)
                  sfputr(sp, internal.make->name, ' ');
            if (r->property & P_multiple)
                  sfputr(sp, internal.multiple->name, ' ');
            if (r->action && !*r->action)
                  sfputr(sp, internal.null->name, ' ');
            if (r->property & P_archive)
                  sfputr(sp, internal.archive->name, ' ');
            if (r->property & P_command)
                  sfputr(sp, internal.command->name, ' ');
            if (r->property & P_ignore)
                  sfputr(sp, internal.ignore->name, ' ');
            if (r->property & P_immediate)
                  sfputr(sp, internal.immediate->name, ' ');
            if (r->property & P_implicit)
                  sfputr(sp, internal.implicit->name, ' ');
            if (r->property & P_local)
                  sfputr(sp, internal.local->name, ' ');
            if (r->property & P_operator)
                  sfputr(sp, internal.op->name, ' ');
            if (r->property & P_parameter)
                  sfputr(sp, internal.parameter->name, ' ');
            if (r->property & P_repeat)
                  sfputr(sp, internal.repeat->name, ' ');
            if (r->semaphore)
                  for (n = r->semaphore - 1; n; n--)
                        sfputr(sp, internal.semaphore->name, ' ');
            if (r->property & P_terminal)
                  sfputr(sp, internal.terminal->name, ' ');
            if ((r->property & (P_metarule|P_use))
                  == P_use) sfputr(sp, internal.use->name, ' ');
            if (r->property & P_virtual)
                  sfputr(sp, internal.virt->name, ' ');
      }
      if (p = r->prereqs)
      {
            if (dumpall || !state.list)
                  sfputr(sp, " prerequisites:", ' ');
            for (; p; p = p->next)
                  dumpname(sp, p->rule, " ");
            sfputc(sp, '\n');
      }
      else if (!dumpall && state.list)
            sfputc(sp, '\n');
      if (r->action && *r->action)
      {
            if (dumpall || !state.list)
                  sfputr(sp, " action:", '\n');
            dumpaction(sp, NiL, r->action, "\t");
      }
      if ((dumpall || !state.list) && (r->property & P_statevar) && r->statedata)
            sfprintf(sp, " state: %s\n", r->statedata);
      return 0;
}

/*
 * list a single variable and its value
 */

static int
listvar(const char* s, char* u, void* h)
{
      register Var_t*         v = (Var_t*)u;
      register char*          t;
      register char*          q;
      register Sfio_t*  sp = (Sfio_t*)h;

      if (dumpall || !(v->property & V_import) && (!state.list || !isintvar(v->name)))
      {
            if (!dumpall && state.list)
            {
                  for (q = (char*)s; istype(*q, C_ID1|C_ID2); q++);
                  if (*q)
                        q = "\"";
            }
            else
                  q = null;
            sfprintf(sp, "%s%s%s ", q, s, q);
#if DEBUG
            if (state.test & 0x00004000)
                  sfprintf(sp, "@%p ", v);
#endif
            if (dumpall || !state.list)
            {
                  sfputr(sp, "[", ' ');
                  if (v->property & V_append)
                        sfputr(sp, "append", ' ');
                  if (v->property & V_auxiliary)
                        sfputr(sp, "auxiliary", ' ');
                  if (v->property & V_builtin)
                        sfputr(sp, "builtin", ' ');
                  if (v->property & V_free)
                        sfputr(sp, "free", ' ');
                  if (v->property & V_frozen)
                        sfputr(sp, "frozen", ' ');
                  if (v->property & V_functional)
                        sfputr(sp, "functional", ' ');
                  if (v->property & V_import)
                        sfputr(sp, "import", ' ');
                  if (v->property & V_local_D)
                        sfputr(sp, "local_D", ' ');
                  if (v->property & V_local_E)
                        sfputr(sp, "local_E", ' ');
                  if (v->property & V_oldvalue)
                  {
                        sfputr(sp, "oldvalue", -1);
                        if (t = getold(s))
                              sfprintf(sp, "=`%s'", t);
                        sfputc(sp, ' ');
                  }
                  if (v->property & V_readonly)
                        sfputr(sp, "readonly", ' ');
                  if (v->property & V_restored)
                        sfputr(sp, "restored", ' ');
                  if (v->property & V_retain)
                        sfputr(sp, "retain", ' ');
                  if (v->property & V_scan)
                        sfputr(sp, "scan", ' ');
                  if (v->property & V_scope)
                        sfputr(sp, "scope", ' ');
                  sfputr(sp, "]", ' ');
            }
            sfprintf(sp, "= %s", t = v->value);
            if ((v->property & V_auxiliary) && (v = auxiliary(v->name, 0)))
            {
                  if (!dumpall && state.list)
                        sfprintf(sp, "\n%s%s%s ", q, s, q);
                  else if (*t)
                        sfputc(sp, ' ');
                  sfprintf(sp, "&= %s", v->value);
            }
            sfputc(sp, '\n');
      }
      return 0;
}

/*
 * dump rules and variables
 */

void
dump(Sfio_t* sp, int verbose)
{
      static int  dumping;

      if (!dumping++)
      {
            if (state.vardump || state.ruledump)
                  state.list = 0;
            if (verbose)
                  hashdump(NiL, (error_info.trace <= -20) ? HASH_BUCKET : 0);
            if (state.list)
                  sfprintf(sp, "/* %s */\n\n", version);
            if (!dumpall && (state.list || state.vardump))
            {
                  sfprintf(sp, "\n/* Variables */\n\n");
                  hashwalk(table.var, 0, listvar, sp);
            }
            if (!dumpall && (state.list || state.ruledump))
            {
                  sfprintf(sp, "\n/* Rules */\n");
                  hashwalk(table.rule, 0, listrule, sp);
            }
            sfsync(sp);
            dumping--;
      }
}

/*
 * dump regression prefix,name,value
 */

void
dumpregress(register Sfio_t* sp, const char* prefix, const char* name, register char* value)
{
      register int      c;
      register int      n;
      int*        rp;
      char*       bp;
      char*       np;

      static int  index;

      sfprintf(sp, "%s%s %s ", state.mam.label, prefix, name ? name : "-");
      n = -1;
      if (value)
            for (;;)
            {
                  switch (c = *value++)
                  {
                  case 0:
                        break;
                  case '\n':
                        sfprintf(sp, "\n%s%s %s ", state.mam.label, prefix, name ? name : "-");
                        n = 1;
                        continue;
                  case '\t':
                        c = ' ';
                        /*FALLTHROUGH*/
                  case ' ':
                        if (n < 0 || *value == ' ' || *value == '\t' || *value == 0 || *value == '\n')
                              continue;
                        /*FALLTHROUGH*/
                  case '\'':
                  case '"':
                  case '=':
                  case ':':
                        sfputc(sp, c);
                        n = 1;
                        continue;
                  case '/':
                        if (n)
                        {
                              bp = np = value - 1;
                              for (;;)
                              {
                                    switch (*value++)
                                    {
                                    case ' ':
                                    case '\t':
                                    case '\n':
                                    case '\'':
                                    case '"':
                                    case ':':
                                    case 0:
                                          break;
                                    case '/':
                                          np = value - 1;
                                          /*FALLTHROUGH*/
                                    default:
                                          continue;
                                    }
                                    break;
                              }
                              c = *--value;
                              *value = 0;
                              if (strmatch(np, "*.*"))
                              {
                                    *value = c;
                                    c = *(value = np);
                                    *value = 0;
                              }
                              if (!(rp = getreg(bp)))
                              {
                                    rp = newof(0, int, 1, 0);
                                    *rp = ++index;
                                    putreg(0, rp);
                              }
                              sfprintf(sp, "${PATH_%d}", *rp);
                              *value = c;
                              n = 0;
                        }
                        else
                              sfputc(sp, c);
                        continue;
                  case '-':
                  case '+':
                        sfputc(sp, c);
                        if (n)
                        {
                              if (!(c = *value++))
                                    break;
                              sfputc(sp, c);
                              n = isalnum(c) ? 1 : 0;
                        }
                        continue;
                  default:
                        sfputc(sp, c);
                        n = 0;
                        continue;
                  }
                  break;
            }
      sfputc(sp, '\n');
}

/*
 * dump an action placing prefix at the beginning of each line
 */

void
dumpaction(Sfio_t* sp, const char* name, register char* action, register const char* prefix)
{
      register char*    s;
      char*       mamlabel;
      char*       sep;

      if (prefix)
      {
            mamlabel = null;
            name = null;
            sep = null;
      }
      else
      {
            if (state.mam.regress)
            {
                  dumpregress(sp, "exec", name, action);
                  return;
            }
            if (state.mam.out)
            {
                  mamlabel = state.mam.label;
                  prefix = "exec";
                  if (!name)
                        name = "-";
                  sep = " ";
            }
            else
            {
                  while (isspace(*action))
                        action++;
                  if (!*action)
                        return;
                  mamlabel = null;
                  prefix = "+";
                  name = null;
                  sep = null;
            }
      }
      for (;;)
      {
            if (s = strchr(action, '\n'))
                  *s = 0;
            sfprintf(sp, "%s%s %s%s%s\n", mamlabel, prefix, name, sep, action);
            if (!s)
                  break;
            *s++ = '\n';
            action = s;
      }
      sfsync(sp);
}

/*
 * dump variable info
 */

void
dumpvar(Sfio_t* sp, register Var_t* v)
{
      dumpall++;
      listvar(v->name, (char*)v, sp);
      sfsync(sp);
      dumpall--;
}

/*
 * dump rule info
 */

void
dumprule(Sfio_t* sp, register Rule_t* r)
{
      register int            i;
      register Rule_t*  z;

      dumpall++;
      z = 0;
      while ((r->dynamic & D_alias) && r != z)
      {
            listrule(r->name, (char*)r, sp);
            z = r;
            if (!(r = getrule(r->name)))
                  r = z;
      }
      if (r == z)
            error(2, "%s: alias loop", r->name);
      else
            listrule(r->name, (char*)r, sp);
      if (!(r->property & P_state))
            for (i = RULE; i <= STATERULES; i++)
                  if (z = staterule(i, r, NiL, -1))
                        listrule(z->name, (char*)z, sp);
      sfsync(sp);
      dumpall--;
}

Generated by  Doxygen 1.6.0   Back to index