Logo Search packages:      
Sourcecode: ksh version File versions

vcs_search.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1990-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>                  *
*                                                                      *
***********************************************************************/
/*
 *    search.c
 *          cmptime()
 *          search_tag
 *          gettagbyspec()
 *          lookup_tagtime()
 *          lookup_tag_t()
 *          pattern2time()
 *          gettagbytime()
 *          gettagbyname()
 *          rs_readlink()
 */
#include "vcs_rscs.h"
#include <ls.h>
#include <tm.h>


int cmptime(s1, s2)
      const void* s1;
      const void* s2;
{
#define TAGTIME(s)      ((*((rdirent_t**)s))->tag->stat.st_mtime)
      return (TAGTIME(s1) - TAGTIME(s2));
}

/*
 *    versions    ::    version
 *                 |    version ; versions
 *                 |    NULL
 *    version     ::    id 
 *                 |    id distance 
 *    id          ::    string | date_spec
 *    date_spec   ::    [ "(" ] date [ ")" ]
 *    distance    ::    [ "+" | "-" ] integer
 *    date        ::    month day [ time | year]
 *    time        ::    hh ":" mm [ ":" ss ]
 *
 *
 */
int search_tag(rf, ap, versions, domain, tpp, mode, dir)
      Sfio_t*     rf;
      attr_t*           ap;
      char*       versions;
      int         domain;
      tag_t**           tpp;
      int         mode;
      rdirent_t** dir;
{
      register rdirent_t*     list;
      int               r;
      tag_t*                  tp;

      if ((list = rs_dir(rf, ap)) == NULL)
            return (-1);
      if (dir)
            *dir = list;
      if (!versions)
            r = lookup_tag(list, rf, ap, versions, domain, &tp, 0);
      else
            r = gettagbyspec(list, versions, domain, &tp);
      
      if (r)
            return (r);

      if (R_ISLINK(tp) && (mode & G_LINK))
      {
            if ((tp = gettagbyname(list, tp->version, G_LINK, 0)) == NULL)
                  return (-1);
      }
      *tpp = tp;
      return (0);
}



int gettagbyspec(list, versions, domain, tpp)
      register rdirent_t*     list;
      char*             versions;
      int               domain;
      tag_t**                 tpp;
{
      char              buf[2048];
      register char*          s;
      char*             elist[MAXDEPTH+1];
      rdirent_t*        tbl[MAXDEPTH+1];
      register int            i;
      register rdirent_t*     entry;
      int               sort = 0;
      int               total;
      int               num;
      int               flag;
      int               index;
      int               distance;
      time_t                  to;


      for (entry=list, i=0; entry; entry = entry->next, i++)
            tbl[i] = entry;
      total = i;

      strcpy(buf, versions);
      s = buf;
      elist[num=chop(s, elist, MAXDEPTH, ';')] = NULL;

      for (i = 0; i < num; i++)
      {
            distance = 0;
            if ((s = strchr(elist[i], '-')) || (s = strchr(elist[i], '+')))
            {
                  flag = (*s == '+') ? 0 : 1;
                  *s = '\0';
                  s++;
                  distance = (int)strtol(s, (char**)0, 0);
                  if (!sort)
                  {
                        qsort((char *)tbl, total, sizeof(rdirent_t *), cmptime);
                        sort++;
                  }
            }
            if ((index = lookup_tag_t(tbl, total, elist[i], domain, 0)) < 0)
            {
                  if (pattern2time(elist[i], &to) < 0)
                        continue;
                  if (!sort)
                  {
                        qsort((char *)tbl, total, sizeof(rdirent_t *), cmptime);
                        sort++;
                  }
                  if ((index = lookup_tag_time(tbl, total, to, domain, 0)) < 0)
                        continue;
            }
            if (!distance)
            {
                  *tpp = tbl[index]->tag;
                  return (0);
            }
            if (!flag) 
                  index += distance;
            else
                  index -= distance;
            if (index >=0 && index < total)
            {
                  *tpp = tbl[index]->tag;
                  return (0);
            }
      }
      return (-1);
}

int lookup_tag_time(tbl, total, to, domain, first)
      register rdirent_t**    tbl;
      int               total;
      time_t                  to;
      int               domain;
      int               first;
{
      register int            i;
      int               r;

      r = -1;

      for (i = 0; i < total; i++)
      {
            if (tbl[i]->tag->stat.st_mtime > to)
                  return (r);
            if (domain && tbl[i]->tag->domain != domain)
                  continue;
            if (first)
                  return (i);
            r =  i;
      }
      return (r);
}


            
/*
 *    mode = 0    any;
 *    mode = 1    domain must match 
 */

int lookup_tag(entries, rf, ap, version, domain, tpp, mode)
      rdirent_t*        entries;    
      Sfio_t*           rf;
      attr_t*                 ap;
      char*             version;
      int               domain;
      tag_t**                 tpp;
      int               mode;
{
      register rdirent_t*     list;
      register rdirent_t*     p;
      register char*          v;
      rdirent_t*        sp;
      rdirent_t*        ep;
      time_t                  mtime;
      int               cnt = 0;

      if (entries)
            list = entries;
      else if ((list = rs_dir(rf, ap)) == NULL)
            return (-1);

      if (version)
            v = version;
      else
            v = "LATEST";

      for (sp = NULL, ep = NULL, p = list; p; p = p->next)
      {
            if (strcmp(p->tag->version, v) == 0)
            {
                  if (domain)
                  {
                        if (p->tag->domain == domain)
                        {
                              tpp = &(p->tag);
                              return (0);
                        }
                  }
                  else
                  {
                        cnt++;
                        if (!sp)
                              ep = sp = p;
                        else
                              ep = p;
                  }
            }
      }
      if (mode)
            return (-1);

      switch (cnt)
      {
      case 0:
            if (strcmp(v, "BASE") == 0)
            {
                  /* return the base tag */
                  for (p =list; p; p = p->next)
                  {
                        if (ISBASE(p->tag))
                        {
                              tpp = &(p->tag);
                              return (0);
                        }
                  }
                  message((0, "can find the base"));
                  return (-1);
            }
            else if (strcmp(v, "LATEST") == 0)
            {
                  /* return the latest one */
                  for (p = list, mtime = 0L; p; p = p->next)
                  {
                        if (p->tag->stat.st_mtime > mtime)
                        {
                              *tpp = p->tag;
                              mtime = p->tag->stat.st_mtime;
                        }
                  }
                  return (0);
            }
            else
                  return (-1);
      case 1:
            *tpp = sp->tag;
            return (0);
      default:
            /*
             *    return the latest one 
             */
            for (p = sp, mtime = 0L; p != ep->next; p = p->next)
            {
                  if (p->tag->stat.st_mtime > mtime)
                  {
                        *tpp = p->tag;
                        mtime = p->tag->stat.st_mtime;
                  }
            }
            return (0);
      }
}

            
/*
 *    mode = 0    any;
 *    mode = 1    domain must match 
 */

int lookup_tag_t(tbl, total, version, domain, mode)
      register rdirent_t**    tbl;
      int               total;
      char*             version;
      int               domain;
      int               mode;
{
      register char*          v;
      register int            i;
      int               cnt = 0;
      int               r;


      if (version && *version)
            v = version;
      else
            v = "LATEST";

      for (i = 0; i < total; i++)
      {
            if (strcmp(tbl[i]->tag->version, v) == 0)
            {
                  if (domain)
                  {
                        if (tbl[i]->tag->domain == domain)
                              return (i); 
                  }
                  else
                  {
                        cnt++;
                        r = i;
                  }
            }
      }

      if (mode)
            return (-1);

      if (cnt)
            return (r);

      if (strcmp(v, "BASE") == 0 || strcmp(v, "base") == 0)
      {
            for (i = 0; i < total; i++)
            {
                  if (ISBASE(tbl[i]->tag))
                        return (i);
            }
            message((0, "can find the base"));
            return (-1);
      }
      else if (strcmp(v, "LATEST") == 0 || strcmp(v, "LATEST") == 0)
            return (total-1);
      else
            return (-1);

}
                        
static char*  MONTH[12]=
{
      "Jan", "Feb", "Mar", 
      "Apr", "May", "Jun", 
      "Jul", "Aug", "Sep", 
      "Oct", "Nov", "Dec",
};



int pattern2time(pattern, to)
      char*       pattern;
      time_t*           to;
{
      char        buf[1024];
      register char*    s;
      int         dd, yy, hh, mm, ss;
      char        month[10];
      char        tbuf[128];
      int         flag = 0;
      int         mon;


      message((5, "pattern2time ++ [%s]", pattern)); 

#define LINIT()   (yy = 0, ss = 59, mm = 59, hh = 23)

      LINIT();

      if (*pattern == '(')
      {
            for (s=buf, pattern++; *pattern && *pattern != ')'; s++, pattern++)
            {
                  *s = *pattern;
                  if (*s == '/')
                        flag++;
            }
            *s = '\0';
            s = buf;
      }
      else
      {
            s = pattern;
            if (strchr(s, '/'))
                  flag++;
      }
      if (flag)
      {
            if ((sfsscanf(s, "%d/%d/%d", &mon, &dd, &yy)) != 3)
                  return (-1);
            if (mon <= 12)
                  strcpy(month, MONTH[--mon]);
            else if (dd <= 12)
            {
                  strcpy(month, MONTH[--dd]);
                  dd = mon;
            }
            else
                  return (-1);
      }
      else if (
         (LINIT(), sfsscanf(s, "%s %d %d %d:%d:%d", month, &dd, &yy, &hh, &mm, &ss) != 6) &&
           (LINIT(), sfsscanf(s, "%s %d %d:%d:%d", month, &dd, &hh, &mm, &ss) != 5) &&
         (LINIT(), sfsscanf(s, "%s %d %d %d:%d", month, &dd, &yy, &hh, &mm) != 5) &&
         (LINIT(), sfsscanf(s, "%s %d %d:%d", month, &dd, &hh, &mm) != 4) &&
         (LINIT(), sfsscanf(s, "%s %d %d", month, &dd, &yy) != 3) &&
         (LINIT(), sfsscanf(s, "%s %d", month, &dd) != 2))
      {
            message((5, "can't scan --")); 
            return (-1);
      }



      if (yy)
            sfsprintf(tbuf, sizeof(tbuf), "%s %d %d %d:%d:%d", month, dd, yy, hh, mm, ss);
      else
            sfsprintf(tbuf, sizeof(tbuf), "%s %d %d:%d:%d", month, dd, hh, mm, ss);

      message((3, "tbuf [from] %s", tbuf)); 
      *to = tmdate(tbuf, (char **) 0, (time_t *) 0);
      return (0);
}

tag_t* gettagbytime(list, mtime)
      rdirent_t*        list;
      register time_t         mtime;
{
      register rdirent_t*     ep;

      for(ep =list; ep; ep =ep->next)
      {
            if (ep->tag->stat.st_mtime == mtime)
                  return (ep->tag);
      }
      return (NULL);
}

tag_t* gettagbyname(list, name, mode, level)
      rdirent_t*  list;
      char*       name;
      int         mode;
      int         level;
{
      register rdirent_t*     ep;

      if (level > MAXLINKS)
            return (NULL);

      
      for (ep = list; ep; ep = ep->next)
      {
            if (strcmp(ep->tag->version, name) == 0)
            {
                  if (R_ISLINK(ep->tag) && (mode & G_LINK))
                  {
                        return (gettagbyname(list, ep->link, mode, level +1));
                  }
                  return (ep->tag);
            }
      }
      return (NULL);
}


char* rs_readlink(s)
      char* s;
{
      register char*    t;

      if ((t = strrchr(s, CHRLINK)) == NULL)
            return (NULL);
      
      *t = '\0';
      return (++t);
}

Generated by  Doxygen 1.6.0   Back to index