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

Diff for /src/usr.bin/rcs/rcs.c between version 1.24 and 1.25

version 1.24, 2006/07/21 00:21:52 version 1.25, 2006/07/21 00:47:35
Line 2567 
Line 2567 
 static BUF *  static BUF *
 rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)  rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode)
 {  {
         BUF *newbuf;          ptrdiff_t c_offset, sizdiff, start_offset;
           size_t i;
         int kwtype;          int kwtype;
         u_int j, found;          u_int j, found;
         u_char *c, *kwstr, *start, *end, *fin;          u_char *c, *data, *kwstr, *start, *end, *tbuf, *fin;
         char expbuf[256], buf[256];          char expbuf[256], buf[256];
         struct tm tb;          struct tm tb;
         char *fmt;          char *fmt;
         size_t len;          size_t len, tbuflen;
   
         kwtype = 0;          kwtype = 0;
         kwstr = NULL;          kwstr = NULL;
Line 2590 
Line 2591 
   
         c = rcs_buf_get(bp);          c = rcs_buf_get(bp);
         found = 0;          found = 0;
         /* Final character in buffer. */          for (i = 0; i < len; i++) {
         fin = c + len - 1;  
   
         /* If no keywords exist, return original BUF. */  
         while (c < fin && !found) {  
                 if (*c == '$') {                  if (*c == '$') {
                         size_t clen;  
   
                         /* Skip initial `$'. */  
                         c++;                          c++;
                         /* Number of characters between c and fin, inclusive. */                          i++;
                         clen = fin - c + 1;  
                         for (j = 0; j < RCS_NKWORDS; j++) {                          for (j = 0; j < RCS_NKWORDS; j++) {
                                 size_t kwlen;                                  if (!strncmp(c, rcs_expkw[j].kw_str,
                                       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;
Line 2625 
Line 2610 
         if (found == 0)          if (found == 0)
                 return (bp);                  return (bp);
   
         /* If no keywords are found, return original buffer. */          rcs_buf_putc(bp, '\0');
         newbuf = bp;          data = rcs_buf_release(bp);
           c = data;
           fin = c + len;
           len++;
   
         /*          /*
          * Keyword formats:           * Keyword formats:
Line 2635 
Line 2623 
          */           */
         for (; c < fin; 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 2648 
Line 2634 
                                 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++) {
                                 size_t kwlen;                                  if (!strncmp(c, rcs_expkw[j].kw_str,
                                       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;
                                 }                                  }
                         }                          }
Line 2678 
Line 2652 
                                 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 == ':') {
                                 for (; c <= fin; ++c) {                                  while (*c++) {
                                         if (*c == '$' || *c == '\n')                                          if (*c == '$' || *c == '\n')
                                                 break;                                                  break;
                                 }                                  }
Line 2694 
Line 2675 
                                         continue;                                          continue;
                                 }                                  }
                         }                          }
                           c_offset = c - data;
                         end = c + 1;                          end = c + 1;
   
                         /* start constructing the expansion */                          /* start constructing the expansion */
Line 2773 
Line 2755 
                                 if (strlcat(expbuf, "$", sizeof(expbuf)) >= sizeof(expbuf))                                  if (strlcat(expbuf, "$", sizeof(expbuf)) >= sizeof(expbuf))
                                         errx(1, "rcs_expand_keywords: string truncated");                                          errx(1, "rcs_expand_keywords: string truncated");
   
                         /* Concatenate everything together. */                          sizdiff = strlen(expbuf) - (end - start);
                         tmpbuf = rcs_buf_alloc(len + strlen(expbuf), BUF_AUTOEXT);                          tbuflen = fin - end;
                         /* Append everything before keyword. */                          tbuf = xmalloc(tbuflen);
                         rcs_buf_append(tmpbuf, rcs_buf_get(newbuf),                          memcpy(tbuf, end, tbuflen);
                             start - (unsigned char *)rcs_buf_get(newbuf));                          /* only realloc if we have to */
                         /* Append keyword. */                          if (sizdiff > 0) {
                         rcs_buf_append(tmpbuf, expbuf, strlen(expbuf));                                  char *newdata;
                         /* Point c to end of keyword. */  
                         c = rcs_buf_get(tmpbuf) + rcs_buf_len(tmpbuf) - 1;  
                         /* Append everything after keyword. */  
                         rcs_buf_append(tmpbuf, end,  
                             ((unsigned char *)rcs_buf_get(newbuf) + rcs_buf_len(newbuf)) - end);  
                         /* Point fin to end of data. */  
                         fin = rcs_buf_get(tmpbuf) + rcs_buf_len(tmpbuf) - 1;  
   
                         /* tmpbuf is now ready, free old newbuf if allocated here. */                                  len += sizdiff;
                         if (newbuf != bp)                                  newdata = xrealloc(data, 1, len);
                                 rcs_buf_free(newbuf);                                  data = newdata;
                         newbuf = tmpbuf;                                  /*
                                    * ensure string pointers are not invalidated
                                    * after realloc()
                                    */
                                   start = data + start_offset;
                                   fin = data + len;
                                   c = data + c_offset;
                           }
                           memcpy(start, expbuf, strlen(expbuf) + 1);
                           start += strlen(expbuf);
                           memcpy(start, tbuf, tbuflen);
                           xfree(tbuf);
                           c = start + strlen(expbuf);
                 }                  }
         }          }
   
         return (newbuf);          bp = rcs_buf_alloc(len - 1, BUF_AUTOEXT);
           rcs_buf_set(bp, data, len - 1, 0);
           xfree(data);
   
           return (bp);
 }  }
   
 /*  /*

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25