/[CvsGraph]/cvsgraph/cvsgraph.c
ViewVC logotype

Diff of /cvsgraph/cvsgraph.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.29, Tue Feb 11 10:43:44 2003 UTC revision 1.30, Sun Mar 9 22:36:50 2003 UTC
# Line 35  Line 35 
35  #include <ctype.h>  #include <ctype.h>
36  #include <time.h>  #include <time.h>
37  #include <limits.h>  #include <limits.h>
38    #include <regex.h>
39    
40  #ifdef HAVE_GETOPT_H  #ifdef HAVE_GETOPT_H
41  # include <getopt.h>  # include <getopt.h>
# Line 87  Line 88 
88  color_t white_color = {255, 255, 255, 0};  color_t white_color = {255, 255, 255, 0};
89  color_t black_color = {0, 0, 0, 0};  color_t black_color = {0, 0, 0, 0};
90    
91    /*
92     **************************************************************************
93     * Forwards
94     **************************************************************************
95     */
96    static void zap_string(void);
97    static char *dup_string(void);
98    static void add_string_str(const char *s);
99    static void add_string_ch(int ch);
100    static void add_string_date(const char *d);
101    static void add_string_str_html(const char *s, int maxlen);
102    static void add_string_str_len(const char *s, int maxlen);
103    
104  /*  /*
105   **************************************************************************   **************************************************************************
# Line 629  Line 642 
642          return r;          return r;
643  }  }
644    
645    static char *build_regex(size_t n, regmatch_t *m, const char *ms)
646    {
647            char *cptr;
648            int i;
649    
650            if(!conf.merge_to || !conf.merge_to[0])
651                    return NULL;
652    
653            zap_string();
654            for(cptr = conf.merge_to; *cptr; cptr++)
655            {
656                    if(*cptr == '%')
657                    {
658                            if(cptr[1] >= '1' && cptr[1] <= '9')
659                            {
660                                    int idx = cptr[1] - '0';
661                                    regmatch_t *p = &m[idx];
662                                    if(idx < n && !(p->rm_so == -1 || p->rm_so >= p->rm_eo))
663                                    {
664                                            for(i = p->rm_so; i < p->rm_eo; i++)
665                                            {
666                                                    if(strchr("^$.*+\\[{()", ms[i]))
667                                                            add_string_ch('\\');
668                                                    add_string_ch(ms[i]);
669                                            }
670                                    }
671                                    cptr++;
672                            }
673                            else
674                                    add_string_ch('%');
675                    }
676                    else
677                            add_string_ch(*cptr);
678            }
679            return dup_string();
680    }
681    
682  int assign_tags(rcsfile_t *rcs)  int assign_tags(rcsfile_t *rcs)
683  {  {
684          int i;          int i;
685          int nr;          int nr;
686            int err;
687            regex_t *refrom = NULL;
688            regex_t *reto = NULL;
689            regmatch_t *matchfrom = NULL;
690    
691            if(conf.merge_from && conf.merge_from[0] && conf.merge_to && conf.merge_to[0])
692            {
693                    refrom = xmalloc(sizeof(*refrom));
694                    reto = xmalloc(sizeof(*reto));
695    
696                    /* Compile the 'from' regex match for merge identification */
697                    err = regcomp(refrom, conf.merge_from, REG_EXTENDED | (conf.merge_nocase ? REG_ICASE : 0));
698                    if(err)
699                    {
700                            if(!quiet)
701                            {
702                                    char *msg;
703                                    i = regerror(err, refrom, NULL, 0);
704                                    msg = xmalloc(i+1);
705                                    regerror(err, refrom, msg, i+1);
706                                    fprintf(stderr, "%s\n", msg);
707                                    xfree(msg);
708                            }
709                            xfree(refrom);
710                            xfree(reto);
711                            refrom = NULL;
712                            reto = NULL;
713                    }
714                    else
715                            matchfrom = xmalloc((refrom->re_nsub+1) * sizeof(*matchfrom));
716            }
717    
718          for(i = nr = 0; i < rcs->nbranches; i++)          for(i = nr = 0; i < rcs->nbranches; i++)
719                  nr += rcs->branches[i]->nrevs;                  nr += rcs->branches[i]->nrevs;
# Line 724  Line 805 
805                          else                          else
806                          {                          {
807                                  revision_t *rr = *r;                                  revision_t *rr = *r;
808                                    t->logrev = rr;
809                                  if(!conf.rev_maxtags || rr->ntags <= conf.rev_maxtags)                                  if(!conf.rev_maxtags || rr->ntags <= conf.rev_maxtags)
810                                  {                                  {
811                                          rr->tags = xrealloc(rr->tags, (rr->ntags+1)*sizeof(rr->tags[0]));                                          rr->tags = xrealloc(rr->tags, (rr->ntags+1)*sizeof(rr->tags[0]));
# Line 737  Line 819 
819                                                  rr->tags[rr->ntags] = t;                                                  rr->tags[rr->ntags] = t;
820                                          rr->ntags++;                                          rr->ntags++;
821                                  }                                  }
822    
823                                    /* Try to find merge tag matches */
824                                    if(refrom && !regexec(refrom, t->tag, refrom->re_nsub+1, matchfrom, 0))
825                                    {
826                                            int n;
827                                            char *to;
828    
829                                            to = build_regex(refrom->re_nsub+1, matchfrom, t->tag);
830                                            if(to)
831                                            {
832                                                    err = regcomp(reto, to, REG_EXTENDED | (conf.merge_nocase ? REG_ICASE : 0));
833                                                    if(err && !quiet)
834                                                    {
835                                                            char *msg;
836                                                            i = regerror(err, reto, NULL, 0);
837                                                            msg = xmalloc(i+1);
838                                                            regerror(err, reto, msg, i+1);
839                                                            fprintf(stderr, "%s\n", msg);
840                                                    }
841                                                    else if(!err)
842                                                    {
843                                                            for(n = 0; n < rcs->tags->ntags; n++)
844                                                            {
845                                                                    /* From and To never should match the same tag */
846                                                                    if(n == i)
847                                                                            continue;
848    
849                                                                    if(!regexec(reto, rcs->tags->tags[n]->tag, 0, NULL, REG_NOSUB))
850                                                                    {
851                                                                            /* Tag matches */
852                                                                            rcs->merges = xrealloc(rcs->merges,
853                                                                                            sizeof(rcs->merges[0]) * (rcs->nmerges+1));
854                                                                            rcs->merges[rcs->nmerges].to = rcs->tags->tags[n];
855                                                                            rcs->merges[rcs->nmerges].from = t;
856                                                                            rcs->nmerges++;
857                                                                            /* We cannot (should not) match multiple times */
858                                                                            n = rcs->tags->ntags;
859                                                                    }
860                                                            }
861                                                            regfree(reto);
862                                                    }
863                                                    xfree(to);
864                                            }
865                                    }
866                          }                          }
867                  }                  }
868          }          }
# Line 753  Line 879 
879                  *b = rcs->branches[0];                  *b = rcs->branches[0];
880                  rcs->branches[0] = t;                  rcs->branches[0] = t;
881          }          }
882            if(matchfrom)   xfree(matchfrom);
883            if(refrom)      { regfree(refrom); xfree(refrom); }
884            if(reto)        xfree(reto);
885          return 1;          return 1;
886  }  }
887    
# Line 765  Line 894 
894  static int _nstring;  static int _nstring;
895  static int _nastring;  static int _nastring;
896    
897    static void zap_string(void)
898    {
899            _nstring = 0;
900            if(_string)
901                    _string[0] = '\0';
902    }
903    
904    static char *dup_string(void)
905    {
906            if(_string)
907                    return xstrdup(_string);
908            else
909                    return "";
910    }
911    
912  static void add_string_str(const char *s)  static void add_string_str(const char *s)
913  {  {
914          int l = strlen(s) + 1;          int l = strlen(s) + 1;
# Line 837  Line 981 
981                                          cptr += sprintf(cptr, "<br>");                                          cptr += sprintf(cptr, "<br>");
982                          }                          }
983                  }                  }
984                  else if(*s >= 0x7f)                  else if(*s >= 0x7f || *s == '"')
985                          cptr += sprintf(cptr, "&#%d;", (int)(unsigned char)*s);                          cptr += sprintf(cptr, "&#%d;", (int)(unsigned char)*s);
986                  else if(*s == '<')                  else if(*s == '<')
987                          cptr += sprintf(cptr, "&lt;");                          cptr += sprintf(cptr, "&lt;");
# Line 868  Line 1012 
1012          char nb[32];          char nb[32];
1013          char nr[32];          char nr[32];
1014          char *base;          char *base;
1015            char *exp;
1016          int l;          int l;
1017          char ch;          char ch;
1018    
1019          if(!s)          if(!s)
1020                  return xstrdup("");                  return xstrdup("");
1021    
1022          _nstring = 0;          zap_string();
         if(_string)  
                 _string[0] = '\0';  
1023    
1024          sprintf(nb, "%d", rcs->nbranches);          sprintf(nb, "%d", rcs->nbranches);
1025          sprintf(nr, "%d", rcs->nsrev);          sprintf(nr, "%d", rcs->nsrev);
# Line 986  Line 1129 
1129                                                  add_string_str_len(r->dtext->log, abs(l));                                                  add_string_str_len(r->dtext->log, abs(l));
1130                                  }                                  }
1131                                  break;                                  break;
1132                            case '(':
1133                                    base = dup_string();
1134                                    exp = expand_string(s+1, rcs, r, rev, prev, tag);
1135                                    zap_string();
1136                                    add_string_str(base);
1137                                    add_string_str_html(exp, 0);
1138                                    xfree(base);
1139                                    xfree(exp);
1140                                    /* Find the %) in this recursion level */
1141                                    for(; *s; s++)
1142                                    {
1143                                            if(*s == '%' && s[1] == ')')
1144                                                    break;
1145                                    }
1146                                    if(!*s)
1147                                    {
1148                                            s--;    /* To end outer loop */
1149                                            if(!quiet)
1150                                                    fprintf(stderr, "string expand: Missing %%) in expansion\n");
1151                                    }
1152                                    break;
1153                            case ')':
1154                                    return dup_string();
1155                          default:                          default:
1156                                  add_string_ch('%');                                  add_string_ch('%');
1157                                  add_string_ch(*s);                                  add_string_ch(*s);
# Line 995  Line 1161 
1161                  else                  else
1162                          add_string_ch(*s);                          add_string_ch(*s);
1163          }          }
1164          return xstrdup(_string);          return dup_string();
1165  }  }
1166    
1167  /*  /*
# Line 1399  Line 1565 
1565          }          }
1566  }  }
1567    
1568    static void draw_merges(gdImagePtr im, rcsfile_t *rcs)
1569    {
1570            int i;
1571            for(i = 0; i < rcs->nmerges; i++)
1572            {
1573                    revision_t *fr = rcs->merges[i].from->logrev;
1574                    revision_t *tr = rcs->merges[i].to->logrev;
1575                    int x1, x2, y1, y2;
1576                    if(!fr || !tr)
1577                            continue;       /* This can happen with detached tags */
1578                    if(conf.left_right)
1579                    {
1580                            if(fr->y < tr->y)
1581                            {
1582                                    y1 = fr->y + fr->h/2;
1583                                    y2 = tr->y - tr->h/2;
1584                            }
1585                            else
1586                            {
1587                                    y1 = fr->y - fr->h/2;
1588                                    y2 = tr->y + tr->h/2;
1589                            }
1590                            x1 = fr->cx + fr->w/2;
1591                            x2 = tr->cx + tr->w/2;
1592                    }
1593                    else
1594                    {
1595                            if(fr->cx < tr->cx)
1596                            {
1597                                    x1 = fr->cx + fr->w/2;
1598                                    x2 = tr->cx - tr->w/2;
1599                            }
1600                            else
1601                            {
1602                                    x1 = fr->cx - fr->w/2;
1603                                    x2 = tr->cx + tr->w/2;
1604                            }
1605                            y1 = fr->y + fr->h/2;
1606                            y2 = tr->y + tr->h/2;
1607                    }
1608                    gdImageArc(im, x2, y2, 8, 8, 0, 360, conf.merge_color.id);
1609                    gdImageFillToBorder(im, x2, y2, conf.merge_color.id, conf.merge_color.id);
1610                    if(conf.left_right)
1611                    {
1612                            if(y1 > y2)
1613                            {
1614                                    gdImageLine(im, x1, y1, x1, y1-3, conf.merge_color.id);
1615                                    gdImageLine(im, x2, y2+1, x2, y2+3+1, conf.merge_color.id);
1616                                    gdImageLine(im, x1, y1-3, x2, y2+3+1, conf.merge_color.id);
1617                            }
1618                            else
1619                            {
1620                                    gdImageLine(im, x1, y1+1, x1, y1+3+1, conf.merge_color.id);
1621                                    gdImageLine(im, x2, y2, x2, y2-3, conf.merge_color.id);
1622                                    gdImageLine(im, x1, y1+3+1, x2, y2-3, conf.merge_color.id);
1623                            }
1624                    }
1625                    else
1626                    {
1627                            if(x1 > x2)
1628                            {
1629                                    gdImageLine(im, x1, y1, x1-3, y1, conf.merge_color.id);
1630                                    gdImageLine(im, x2, y2, x2+3, y2, conf.merge_color.id);
1631                                    gdImageLine(im, x1-3, y1, x2+3, y2, conf.merge_color.id);
1632                            }
1633                            else
1634                            {
1635                                    gdImageLine(im, x1, y1, x1+3, y1, conf.merge_color.id);
1636                                    gdImageLine(im, x2, y2, x2-3, y2, conf.merge_color.id);
1637                                    gdImageLine(im, x1+3, y1, x2-3, y2, conf.merge_color.id);
1638                            }
1639                    }
1640            }
1641    }
1642    
1643  static void alloc_color(gdImagePtr im, color_t *c)  static void alloc_color(gdImagePtr im, color_t *c)
1644  {  {
1645          c->id = gdImageColorAllocate(im, c->r, c->g, c->b);          c->id = gdImageColorAllocate(im, c->r, c->g, c->b);
# Line 1424  Line 1665 
1665          alloc_color(im, &conf.branch_tag_color);          alloc_color(im, &conf.branch_tag_color);
1666          alloc_color(im, &conf.branch_bgcolor);          alloc_color(im, &conf.branch_bgcolor);
1667          alloc_color(im, &conf.title_color);          alloc_color(im, &conf.title_color);
1668            alloc_color(im, &conf.merge_color);
1669          alloc_color(im, &black_color);          alloc_color(im, &black_color);
1670          alloc_color(im, &white_color);          alloc_color(im, &white_color);
1671    
1672          if(conf.transparent_bg)          if(conf.transparent_bg)
1673                  gdImageColorTransparent(im, conf.color_bg.id);                  gdImageColorTransparent(im, conf.color_bg.id);
1674    
1675            if(!conf.merge_front)
1676                    draw_merges(im, rcs);
1677    
1678          for(i = 0; i < rcs->nbranches; i++)          for(i = 0; i < rcs->nbranches; i++)
1679                  draw_branch(im, rcs->branches[i]);                  draw_branch(im, rcs->branches[i]);
1680          for(i = 0; i < rcs->nbranches; i++)          for(i = 0; i < rcs->nbranches; i++)
# Line 1440  Line 1685 
1685          draw_stringnl(im, cptr, &conf.title_font, conf.title_x, conf.title_y, conf.title_align, &conf.title_color);          draw_stringnl(im, cptr, &conf.title_font, conf.title_x, conf.title_y, conf.title_align, &conf.title_color);
1686          xfree(cptr);          xfree(cptr);
1687    
1688            if(conf.merge_front)
1689                    draw_merges(im, rcs);
1690    
1691          return im;          return im;
1692  }  }
1693    
# Line 2633  Line 2881 
2881          conf.map_diff_href      = xstrdup("href=\"unset: conf.map_diff_href\"");          conf.map_diff_href      = xstrdup("href=\"unset: conf.map_diff_href\"");
2882          conf.map_diff_alt       = xstrdup("alt=\"%P &lt;-&gt; %R\"");          conf.map_diff_alt       = xstrdup("alt=\"%P &lt;-&gt; %R\"");
2883          conf.rev_text           = xstrdup("%d");          conf.rev_text           = xstrdup("%d");
2884            conf.merge_from         = xstrdup("");
2885            conf.merge_to           = xstrdup("");
2886    
2887          conf.color_bg           = white_color;          conf.color_bg           = white_color;
2888          conf.branch_bgcolor     = white_color;          conf.branch_bgcolor     = white_color;
# Line 2640  Line 2890 
2890          conf.branch_tag_color   = black_color;          conf.branch_tag_color   = black_color;
2891          conf.rev_color          = black_color;          conf.rev_color          = black_color;
2892          conf.rev_bgcolor        = white_color;          conf.rev_bgcolor        = white_color;
2893            conf.merge_color        = black_color;
2894          conf.tag_color          = black_color;          conf.tag_color          = black_color;
2895          conf.title_color        = black_color;          conf.title_color        = black_color;
2896          conf.rev_text_color     = black_color;          conf.rev_text_color     = black_color;

Legend:
Removed from v.1.29  
changed lines
  Added in v.1.30

  ViewVC Help
Powered by ViewVC 1.1.0 with CvsGraph 1.7.0