[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.23 and 1.24

version 1.23, 2006/07/11 18:36:32 version 1.24, 2006/07/21 00:21:52
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)
 {  {
         ptrdiff_t c_offset, sizdiff, start_offset;          BUF *newbuf;
         size_t i;  
         int kwtype;          int kwtype;
         u_int j, found;          u_int j, found;
         u_char *c, *data, *kwstr, *start, *end, *tbuf, *fin;          u_char *c, *kwstr, *start, *end, *fin;
         char expbuf[256], buf[256];          char expbuf[256], buf[256];
         struct tm tb;          struct tm tb;
         char *fmt;          char *fmt;
         size_t len, tbuflen;          size_t len;
   
         kwtype = 0;          kwtype = 0;
         kwstr = NULL;          kwstr = NULL;
Line 2591 
Line 2590 
   
         c = rcs_buf_get(bp);          c = rcs_buf_get(bp);
         found = 0;          found = 0;
         for (i = 0; i < len; i++) {          /* Final character in buffer. */
           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++;
                         i++;                          /* Number of characters between c and fin, inclusive. */
                           clen = fin - c + 1;
                         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;
Line 2610 
Line 2625 
         if (found == 0)          if (found == 0)
                 return (bp);                  return (bp);
   
         rcs_buf_putc(bp, '\0');          /* If no keywords are found, return original buffer. */
         data = rcs_buf_release(bp);          newbuf = bp;
         c = data;  
         fin = c + len;  
         len++;  
   
         /*          /*
          * Keyword formats:           * Keyword formats:
Line 2623 
Line 2635 
          */           */
         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 2634 
Line 2648 
                                 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;
                                 }                                  }
                         }                          }
Line 2652 
Line 2678 
                                 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 2675 
Line 2694 
                                         continue;                                          continue;
                                 }                                  }
                         }                          }
                         c_offset = c - data;  
                         end = c + 1;                          end = c + 1;
   
                         /* start constructing the expansion */                          /* start constructing the expansion */
Line 2755 
Line 2773 
                                 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");
   
                         sizdiff = strlen(expbuf) - (end - start);                          /* Concatenate everything together. */
                         tbuflen = fin - end;                          tmpbuf = rcs_buf_alloc(len + strlen(expbuf), BUF_AUTOEXT);
                         tbuf = xmalloc(tbuflen);                          /* Append everything before keyword. */
                         memcpy(tbuf, end, tbuflen);                          rcs_buf_append(tmpbuf, rcs_buf_get(newbuf),
                         /* only realloc if we have to */                              start - (unsigned char *)rcs_buf_get(newbuf));
                         if (sizdiff > 0) {                          /* Append keyword. */
                                 char *newdata;                          rcs_buf_append(tmpbuf, expbuf, strlen(expbuf));
                           /* 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;
   
                                 len += sizdiff;                          /* tmpbuf is now ready, free old newbuf if allocated here. */
                                 newdata = xrealloc(data, 1, len);                          if (newbuf != bp)
                                 data = newdata;                                  rcs_buf_free(newbuf);
                                 /*                          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);  
                 }                  }
         }          }
   
         bp = rcs_buf_alloc(len - 1, BUF_AUTOEXT);          return (newbuf);
         rcs_buf_set(bp, data, len - 1, 0);  
         xfree(data);  
   
         return (bp);  
 }  }
   
 /*  /*

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