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

Diff for /src/usr.bin/rcs/ci.c between version 1.97 and 1.98

version 1.97, 2006/02/16 17:30:46 version 1.98, 2006/02/16 17:44:53
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
 /*  /*
  * Copyright (c) 2005 Niall O'Higgins <niallo@openbsd.org>   * Copyright (c) 2005, 2006 Niall O'Higgins <niallo@openbsd.org>
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 33 
Line 33 
 #define DATE_NOW        -1  #define DATE_NOW        -1
 #define DATE_MTIME      -2  #define DATE_MTIME      -2
   
   #define KW_ID           "Id"
   #define KW_AUTHOR       "Author"
   #define KW_DATE         "Date"
   #define KW_STATE        "State"
   #define KW_REVISION     "Revision"
   #define KW_TYPE_ID       1
   #define KW_TYPE_AUTHOR   2
   #define KW_TYPE_DATE     3
   #define KW_TYPE_STATE    4
   #define KW_TYPE_REVISION 5
   #define KW_NUMTOKS_ID      10
   #define KW_NUMTOKS_AUTHOR   3
   #define KW_NUMTOKS_DATE     4
   #define KW_NUMTOKS_STATE    3
   #define KW_NUMTOKS_REVISION 3
   
 #define LOG_INIT        "Initial revision"  #define LOG_INIT        "Initial revision"
 #define LOG_PROMPT      "enter log message, terminated with a single '.' "    \  #define LOG_PROMPT      "enter log message, terminated with a single '.' "    \
                         "or end of file:\n>> "                          "or end of file:\n>> "
Line 40 
Line 56 
                         "or end of file:\nNOTE: This is NOT the log message!" \                          "or end of file:\nNOTE: This is NOT the log message!" \
                         "\n>> "                          "\n>> "
   
   extern struct rcs_kw rcs_expkw[];
   
 struct checkin_params {  struct checkin_params {
         int flags, openflags;          int flags, openflags;
         mode_t fmode;          mode_t fmode;
Line 47 
Line 65 
         RCSFILE *file;          RCSFILE *file;
         RCSNUM *frev, *newrev;          RCSNUM *frev, *newrev;
         char fpath[MAXPATHLEN], *rcs_msg, *username, *deltatext, *filename;          char fpath[MAXPATHLEN], *rcs_msg, *username, *deltatext, *filename;
         char *author;          char *author, *state;
         const char *symbol, *state, *description;          const char *symbol, *description;
 };  };
   
 static int       checkin_attach_symbol(struct checkin_params *);  static int       checkin_attach_symbol(struct checkin_params *);
Line 59 
Line 77 
 static char     *checkin_getinput(const char *);  static char     *checkin_getinput(const char *);
 static char     *checkin_getlogmsg(RCSNUM *, RCSNUM *);  static char     *checkin_getlogmsg(RCSNUM *, RCSNUM *);
 static int       checkin_init(struct checkin_params *);  static int       checkin_init(struct checkin_params *);
   static int       checkin_keywordscan(char *, RCSNUM **, time_t *, char **,
       char **);
   static int       checkin_keywordtype(char *);
 static int       checkin_mtimedate(struct checkin_params *);  static int       checkin_mtimedate(struct checkin_params *);
   static void      checkin_parsekeyword(char *, RCSNUM **, time_t *, char **,
       char **);
 static int       checkin_update(struct checkin_params *);  static int       checkin_update(struct checkin_params *);
 static void      checkin_revert(struct checkin_params *);  static void      checkin_revert(struct checkin_params *);
   
Line 89 
Line 112 
   
         pb.date = DATE_NOW;          pb.date = DATE_NOW;
         pb.file = NULL;          pb.file = NULL;
         pb.rcs_msg = pb.username = pb.author = NULL;          pb.rcs_msg = pb.username = pb.author = pb.state = NULL;
         pb.state = pb.symbol = pb.description = NULL;          pb.symbol = pb.description = NULL;
         pb.newrev =  NULL;          pb.newrev =  NULL;
         pb.fmode = pb.flags = status = 0;          pb.fmode = pb.flags = status = 0;
   
Line 122 
Line 145 
                         pb.openflags &= ~RCS_CREATE;                          pb.openflags &= ~RCS_CREATE;
                         pb.flags &= ~CI_INIT;                          pb.flags &= ~CI_INIT;
                         break;                          break;
                   case 'k':
                           rcs_set_rev(rcs_optarg, &pb.newrev);
                           pb.flags |= CI_KEYWORDSCAN;
                           break;
                 case 'l':                  case 'l':
                         rcs_set_rev(rcs_optarg, &pb.newrev);                          rcs_set_rev(rcs_optarg, &pb.newrev);
                         pb.flags |= CO_LOCK;                          pb.flags |= CO_LOCK;
Line 557 
Line 584 
   
         filec = (char *)cvs_buf_release(bp);          filec = (char *)cvs_buf_release(bp);
   
           /* Get default values from working copy if -k specified */
           if (pb->flags & CI_KEYWORDSCAN)
                   checkin_keywordscan(filec, &pb->newrev, &pb->date, &pb->state,
                       &pb->author);
   
         /* Get description from user */          /* Get description from user */
         if (pb->description == NULL)          if (pb->description == NULL)
                 rcs_desc = (const char *)checkin_getdesc();                  rcs_desc = (const char *)checkin_getdesc();
Line 801 
Line 833 
                 }                  }
         }          }
         return (basepath);          return (basepath);
   }
   
   /*
    * checkin_keywordscan()
    *
    * Searches working file for keyword values to determine its revision
    * number, creation date and author, and uses these values instead of
    * calculating them locally.
    *
    * Params: The data buffer to scan and pointers to pointers of variables in
    * which to store the outputs.
    *
    * On success, return 0. On error return -1.
    */
   static int
   checkin_keywordscan(char *data, RCSNUM **rev, time_t *date, char **author,
       char **state)
   {
           int kwtype;
           size_t len;
           u_int i, j, found, end;
           char *c, *kwstr, *start, buf[128];
   
           c = start = kwstr = NULL;
   
           i =  found =  0;
           kwtype = 0;
   
           len = strlen(data);
           for (c = data; *c != '\0' && i < len; *c++) {
                   if (*c == '$') {
                           start = c;
                           *c++;
                           if (!isalpha(*c)) {
                                   c = start;
                                   continue;
                           }
                           /* look for any matching keywords */
                           found = 0;
                           for (j = 0; j < 10; j++) {
                                   if (!strncmp(c, rcs_expkw[j].kw_str,
                                       strlen(rcs_expkw[j].kw_str))) {
                                           found = 1;
                                           kwstr = rcs_expkw[j].kw_str;
                                           kwtype = rcs_expkw[j].kw_type;
                                           break;
                                   }
                           }
   
                           /* unknown keyword, continue looking */
                           if (found == 0) {
                                   c = start;
                                   continue;
                           }
   
                           c += strlen(kwstr);
                           if (*c != ':' && *c != '$') {
                                   c = start;
                                   continue;
                           }
   
                           if (*c == ':') {
                                   while (*c++) {
                                           if (*c == '$') {
                                                   end = c - start + 2;
                                                   if (end >= sizeof(buf))
                                                           fatal("keyword buffer"
                                                               " too small!");
                                                   strlcpy(buf, start, end);
                                                   checkin_parsekeyword(buf, rev,
                                                       date, author, state);
                                                   break;
                                           }
                                   }
   
                                   if (*c != '$') {
                                           c = start;
                                           continue;
                                   }
                           }
                   }
           }
           if (found == 0)
                   return (-1);
           else
                   return (0);
   }
   
   /*
    * checkin_keywordtype()
    *
    * Given an RCS keyword string, determine what type of string it is.
    * This enables us to know what data should be in it.
    *
    * Returns type on success, or -1 on failure.
    */
   static int
   checkin_keywordtype(char *keystring)
   {
           char *p;
   
           p = keystring;
           *p++;
           if (strncmp(p, KW_ID, strlen(KW_ID)) == 0)
                   return (KW_TYPE_ID);
           else if (strncmp(p, KW_AUTHOR, strlen(KW_AUTHOR)) == 0)
                   return (KW_TYPE_AUTHOR);
           else if (strncmp(p, KW_DATE, strlen(KW_DATE)) == 0)
                   return (KW_TYPE_DATE);
           else if (strncmp(p, KW_STATE, strlen(KW_STATE)) == 0)
                   return (KW_TYPE_STATE);
           else if (strncmp(p, KW_REVISION, strlen(KW_REVISION)) == 0)
                   return (KW_TYPE_REVISION);
           else
                   return (-1);
   }
   
   /*
    * checkin_parsekeyword()
    *
    * Do the actual parsing of an RCS keyword string, setting the values passed
    * to the function to whatever is found.
    *
    */
   static void
   checkin_parsekeyword(char *keystring,  RCSNUM **rev, time_t *date,
       char **author, char **state)
   {
           char *tokens[10], *p, *datestring;
           size_t len = 0;
           u_int k;
           /* Parse data out of the expanded keyword */
           switch (checkin_keywordtype(keystring)) {
           case KW_TYPE_ID:
                   k = 0;
                   for ((p =strtok(keystring, " ")); p;
                        (p = strtok(NULL, " "))) {
                           if (k < KW_NUMTOKS_ID - 1)
                                   tokens[k++] = p;
                   }
                   tokens[k] = NULL;
                   if (*author != NULL)
                           xfree(*author);
                   if (*state != NULL)
                           xfree(*state);
                   /* only parse revision if one is not already set */
                   if (*rev == NULL) {
                           if ((*rev = rcsnum_parse(tokens[2])) == NULL)
                                   fatal("could not parse rcsnum");
                   }
                   len = strlen(tokens[5]) + 1;
                   *author = xmalloc(len);
                   strlcpy(*author, tokens[5], len);
                   len = strlen(tokens[6]) + 1;
                   *state = xmalloc(len);
                   strlcpy(*state, tokens[6], len);
                   len = strlen(tokens[3]) + strlen(tokens[4]) + 2;
                   datestring = xmalloc(len);
                   strlcpy(datestring, tokens[3], len);
                   strlcat(datestring, " ", len);
                   strlcat(datestring, tokens[4], len);
                   if ((*date = cvs_date_parse(datestring)) <= 0)
                       fatal("could not parse date\n");
                   xfree(datestring);
                   break;
           case KW_TYPE_AUTHOR:
                   k = 0;
                   for ((p =strtok(keystring, " ")); p;
                        (p = strtok(NULL, " "))) {
                           if (k < KW_NUMTOKS_AUTHOR - 1)
                                   tokens[k++] = p;
                   }
                   if (*author != NULL)
                           xfree(*author);
                   len = strlen(tokens[1]) + 1;
                   *author = xmalloc(len);
                   strlcpy(*author, tokens[1], len);
                   break;
           case KW_TYPE_DATE:
                   k = 0;
                   for ((p =strtok(keystring, " ")); p;
                        (p = strtok(NULL, " "))) {
                           if (k < KW_NUMTOKS_DATE - 1)
                                   tokens[k++] = p;
                   }
                   len = strlen(tokens[1]) + strlen(tokens[2]) + 2;
                   datestring = xmalloc(len);
                   strlcpy(datestring, tokens[1], len);
                   strlcat(datestring, " ", len);
                   strlcat(datestring, tokens[2], len);
                   if ((*date = cvs_date_parse(datestring)) <= 0)
                       fatal("could not parse date\n");
                   xfree(datestring);
                   break;
           case KW_TYPE_STATE:
                   k = 0;
                   for ((p =strtok(keystring, " ")); p;
                        (p = strtok(NULL, " "))) {
                           if (k < KW_NUMTOKS_STATE - 1)
                                   tokens[k++] = p;
                   }
                   if (*state != NULL)
                           xfree(*state);
                   len = strlen(tokens[1]) + 1;
                   *state = xmalloc(len);
                   strlcpy(*state, tokens[1], len);
                   break;
           case KW_TYPE_REVISION:
                   /* only parse revision if one is not already set */
                   if (*rev != NULL)
                           break;
                   k = 0;
                   for ((p =strtok(keystring, " ")); p;
                        (p = strtok(NULL, " "))) {
                           if (k < KW_NUMTOKS_REVISION - 1)
                                   tokens[k++] = p;
                   }
                   if ((*rev = rcsnum_parse(tokens[1])) == NULL)
                           fatal("could not parse rcsnum");
                   break;
           }
   
           return;
 }  }

Legend:
Removed from v.1.97  
changed lines
  Added in v.1.98