[BACK]Return to rcs.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cvs

Diff for /src/usr.bin/cvs/rcs.c between version 1.186 and 1.187

version 1.186, 2006/07/30 03:47:48 version 1.187, 2006/08/02 03:23:40
Line 235 
Line 235 
 static void     rcs_growbuf(RCSFILE *);  static void     rcs_growbuf(RCSFILE *);
 static void     rcs_strprint(const u_char *, size_t, FILE *);  static void     rcs_strprint(const u_char *, size_t, FILE *);
   
 static char*   rcs_expand_keywords(char *, struct rcs_delta *, char *,  static BUF      *rcs_expand_keywords(char *, struct rcs_delta *, BUF *, int);
                     size_t, int);  
   
 RCSFILE *  RCSFILE *
 rcs_open(const char *path, int fd, int flags, ...)  rcs_open(const char *path, int fd, int flags, ...)
Line 2570 
Line 2569 
  *   *
  * On error, return NULL.   * On error, return NULL.
  */   */
 static char *  static BUF *
 rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, char *data,  rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
     size_t len, int mode)  
 {  {
         ptrdiff_t c_offset, sizdiff, start_offset;          BUF *newbuf;
         size_t i;  
         int kwtype;          int kwtype;
         u_int j, found;          u_int j, found;
         char *c, *kwstr, *start, *end, *tbuf;          u_char *c, *kwstr, *start, *end, *fin;
         char expbuf[256], buf[256];          char expbuf[256], buf[256];
           struct tm tb;
         char *fmt;          char *fmt;
           size_t len;
   
         kwtype = 0;          kwtype = 0;
         kwstr = NULL;          kwstr = NULL;
         i = 0;  
   
           len = cvs_buf_len(bp);
   
           c = cvs_buf_get(bp);
           found = 0;
           /* Final character in buffer. */
           fin = c + len - 1;
   
           /* If no keywords are found, return original buffer. */
           newbuf = bp;
   
         /*          /*
          * Keyword formats:           * Keyword formats:
          * $Keyword$           * $Keyword$
          * $Keyword: value$           * $Keyword: value$
          */           */
         for (c = data; *c != '\0' && i < len; c++) {          for (; c < fin; c++) {
                 if (*c == '$') {                  if (*c == '$') {
                           BUF *tmpbuf;
                           size_t clen;
   
                         /* remember start of this possible keyword */                          /* remember start of this possible keyword */
                         start = c;                          start = c;
                         start_offset = start - data;  
   
                         /* first following character has to be alphanumeric */                          /* first following character has to be alphanumeric */
                         c++;                          c++;
Line 2604 
Line 2614 
                                 continue;                                  continue;
                         }                          }
   
                           /* Number of characters between c and fin, inclusive. */
                           clen = fin - c + 1;
   
                         /* look for any matching keywords */                          /* look for any matching keywords */
                         found = 0;                          found = 0;
                         for (j = 0; j < RCS_NKWORDS; j++) {                          for (j = 0; j < RCS_NKWORDS; j++) {
                                 if (!strncmp(c, rcs_expkw[j].kw_str,                                  size_t kwlen;
                                     strlen(rcs_expkw[j].kw_str))) {  
                                   kwlen = strlen(rcs_expkw[j].kw_str);
                                   /*
                                    * kwlen must be less than clen since clen
                                    * includes either a terminating `$' or a `:'.
                                    */
                                   if (kwlen < clen &&
                                       memcmp(c, rcs_expkw[j].kw_str, kwlen) == 0 &&
                                       (c[kwlen] == '$' || c[kwlen] == ':')) {
                                         found = 1;                                          found = 1;
                                         kwstr = rcs_expkw[j].kw_str;                                          kwstr = rcs_expkw[j].kw_str;
                                         kwtype = rcs_expkw[j].kw_type;                                          kwtype = rcs_expkw[j].kw_type;
                                           c += kwlen;
                                         break;                                          break;
                                 }                                  }
                         }                          }
   
                         if (cvs_tagname != NULL &&  
                             !strncmp(c, cvs_tagname, strlen(cvs_tagname)) &&  
                             found != 1) {  
                                 found = 1;  
                                 kwstr = cvs_tagname;  
                                 kwtype = RCS_KW_ID;  
                         }  
   
                         /* unknown keyword, continue looking */                          /* unknown keyword, continue looking */
                         if (found == 0) {                          if (found == 0) {
                                 c = start;                                  c = start;
                                 continue;                                  continue;
                         }                          }
   
                         /* next character has to be ':' or '$' */  
                         c += strlen(kwstr);  
                         if (*c != ':' && *c != '$') {  
                                 c = start;  
                                 continue;  
                         }  
   
                         /*                          /*
                          * if the next character was ':' we need to look for                           * if the next character was ':' we need to look for
                          * an '$' before the end of the line to be sure it is                           * an '$' before the end of the line to be sure it is
                          * in fact a keyword.                           * in fact a keyword.
                          */                           */
                         if (*c == ':') {                          if (*c == ':') {
                                 while (*c++) {                                  for (; c <= fin; ++c) {
                                         if (*c == '$' || *c == '\n')                                          if (*c == '$' || *c == '\n')
                                                 break;                                                  break;
                                 }                                  }
Line 2653 
Line 2660 
                                         continue;                                          continue;
                                 }                                  }
                         }                          }
                         c_offset = c - data;  
                         end = c + 1;                          end = c + 1;
   
                         /* start constructing the expansion */                          /* start constructing the expansion */
Line 2731 
Line 2737 
                                     sizeof(expbuf)) >= sizeof(expbuf))                                      sizeof(expbuf)) >= sizeof(expbuf))
                                         fatal("rcs_expand_keywords: truncated");                                          fatal("rcs_expand_keywords: truncated");
   
                         sizdiff = strlen(expbuf) - (end - start);                          /* Concatenate everything together. */
                         tbuf = xstrdup(end);                          tmpbuf = cvs_buf_alloc(len + strlen(expbuf), BUF_AUTOEXT);
                           /* Append everything before keyword. */
                           cvs_buf_append(tmpbuf, cvs_buf_get(newbuf),
                               start - (unsigned char *)cvs_buf_get(newbuf));
                           /* Append keyword. */
                           cvs_buf_append(tmpbuf, expbuf, strlen(expbuf));
                           /* Point c to end of keyword. */
                           c = cvs_buf_get(tmpbuf) + cvs_buf_len(tmpbuf) - 1;
                           /* Append everything after keyword. */
                           cvs_buf_append(tmpbuf, end,
                               ((unsigned char *)cvs_buf_get(newbuf) + cvs_buf_len(newbuf)) - end);
                           /* Point fin to end of data. */
                           fin = cvs_buf_get(tmpbuf) + cvs_buf_len(tmpbuf) - 1;
                           /* Recalculate new length. */
                           len = cvs_buf_len(tmpbuf);
   
                         /* only realloc if we have to */                          /* tmpbuf is now ready, free old newbuf if allocated here. */
                         if (sizdiff > 0) {                          if (newbuf != bp)
                                 char *newdata;                                  cvs_buf_free(newbuf);
                           newbuf = tmpbuf;
                                 len += sizdiff;  
                                 newdata = xrealloc(data, 1, len);  
                                 data = newdata;  
   
                                 /*  
                                  * ensure string pointers are not invalidated  
                                  * after realloc()  
                                  */  
                                 start = data + start_offset;  
                                 c = data + c_offset;  
                         }  
                         if (strlcpy(start, expbuf, len) >= len ||  
                             strlcat(data, tbuf, len) >= len)  
                                 fatal("rcs_expand_keywords: string truncated");  
                         xfree(tbuf);  
                         i += strlen(expbuf);  
                 }                  }
         }          }
   
         return (data);          return (newbuf);
 }  }
   
 /*  /*
Line 2905 
Line 2909 
 rcs_kwexp_buf(BUF *bp, RCSFILE *rf, RCSNUM *rev)  rcs_kwexp_buf(BUF *bp, RCSFILE *rf, RCSNUM *rev)
 {  {
         struct rcs_delta *rdp;          struct rcs_delta *rdp;
         char *expanded, *tbuf;  
         int expmode;          int expmode;
         size_t len;  
   
         /*          /*
          * Do keyword expansion if required.           * Do keyword expansion if required.
Line 2920 
Line 2922 
         if (!(expmode & RCS_KWEXP_NONE)) {          if (!(expmode & RCS_KWEXP_NONE)) {
                 if ((rdp = rcs_findrev(rf, rev)) == NULL)                  if ((rdp = rcs_findrev(rf, rev)) == NULL)
                         fatal("could not fetch revision");                          fatal("could not fetch revision");
                 cvs_buf_putc(bp, '\0');                  return (rcs_expand_keywords(rf->rf_path, rdp, bp, expmode));
                 len = cvs_buf_len(bp);  
                 tbuf = cvs_buf_release(bp);  
                 expanded = rcs_expand_keywords(rf->rf_path, rdp,  
                     tbuf, len, expmode);  
                 bp = cvs_buf_alloc(len, BUF_AUTOEXT);  
                 cvs_buf_set(bp, expanded, strlen(expanded), 0);  
                 xfree(expanded);  
         }          }
         return (bp);          return (bp);
 }  }

Legend:
Removed from v.1.186  
changed lines
  Added in v.1.187