⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subst.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
static svn_error_t *translate_write(svn_stream_t *stream,                const void *buf,                apr_size_t len){  apr_size_t wrote = len;  svn_error_t *write_err = svn_stream_write(stream, buf, &wrote);  if ((write_err) || (len != wrote))    return write_err;  return SVN_NO_ERROR;}/* Perform the substition of VALUE into keyword string BUF (with len   *LEN), given a pre-parsed KEYWORD (and KEYWORD_LEN), and updating   *LEN to the new size of the substituted result.  Return TRUE if all   goes well, FALSE otherwise.  If VALUE is NULL, keyword will be   contracted, else it will be expanded.  */static svn_boolean_ttranslate_keyword_subst(char *buf,                        apr_size_t *len,                        const char *keyword,                        apr_size_t keyword_len,                        const svn_string_t *value){  char *buf_ptr;  /* Make sure we gotz good stuffs. */  assert(*len <= SVN_KEYWORD_MAX_LEN);  assert((buf[0] == '$') && (buf[*len - 1] == '$'));  /* Need at least a keyword and two $'s. */  if (*len < keyword_len + 2)    return FALSE;  /* The keyword needs to match what we're looking for. */  if (strncmp(buf + 1, keyword, keyword_len))    return FALSE;  buf_ptr = buf + 1 + keyword_len;  /* Check for fixed-length expansion.    * The format of fixed length keyword and its data is   * Unexpanded keyword:         "$keyword::       $"   * Expanded keyword:           "$keyword:: value $"   * Expanded kw with filling:   "$keyword:: value   $"   * Truncated keyword:          "$keyword:: longval#$"   */  if ((buf_ptr[0] == ':') /* first char after keyword is ':' */      && (buf_ptr[1] == ':') /* second char after keyword is ':' */      && (buf_ptr[2] == ' ') /* third char after keyword is ' ' */      && ((buf[*len - 2] == ' ')  /* has ' ' for next to last character */          || (buf[*len - 2] == '#')) /* .. or has '#' for next to last                                        character */      && ((6 + keyword_len) < *len))  /* holds "$kw:: x $" at least */    {      /* This is fixed length keyword, so *len remains unchanged */      apr_size_t max_value_len = *len - (6 + keyword_len);      if (! value)        {          /* no value, so unexpand */          buf_ptr += 2;          while (*buf_ptr != '$')            *(buf_ptr++) = ' ';        }      else         {          if (value->len <= max_value_len)             { /* replacement not as long as template, pad with spaces */              strncpy(buf_ptr + 3, value->data, value->len);              buf_ptr += 3 + value->len;              while (*buf_ptr != '$')                *(buf_ptr++) = ' ';            }          else            {              /* replacement needs truncating */              strncpy(buf_ptr + 3, value->data, max_value_len);              buf[*len - 2] = '#';              buf[*len - 1] = '$';            }        }      return TRUE;    }  /* Check for unexpanded keyword. */  else if ((buf_ptr[0] == '$')          /* "$keyword$" */           || ((buf_ptr[0] == ':')                && (buf_ptr[1] == '$'))) /* "$keyword:$" */    {      /* unexpanded... */      if (value)        {          /* ...so expand. */          buf_ptr[0] = ':';          buf_ptr[1] = ' ';          if (value->len)            {              apr_size_t vallen = value->len;              /* "$keyword: value $" */              if (vallen > (SVN_KEYWORD_MAX_LEN - 5 - keyword_len))                vallen = SVN_KEYWORD_MAX_LEN - 5 - keyword_len;              strncpy(buf_ptr + 2, value->data, vallen);              buf_ptr[2 + vallen] = ' ';              buf_ptr[2 + vallen + 1] = '$';              *len = 5 + keyword_len + vallen;            }          else            {              /* "$keyword: $"  */              buf_ptr[2] = '$';              *len = 4 + keyword_len;            }        }      else        {          /* ...but do nothing. */        }      return TRUE;    }  /* Check for expanded keyword. */  else if ((*len >= 4 + keyword_len ) /* holds at least "$keyword: $" */           && (buf_ptr[0] == ':')     /* first char after keyword is ':' */           && (buf_ptr[1] == ' ')     /* second char after keyword is ' ' */           && (buf[*len - 2] == ' ')) /* has ' ' for next to last character */    {      /* expanded... */      if (! value)        {          /* ...so unexpand. */          buf_ptr[0] = '$';          *len = 2 + keyword_len;        }      else        {          /* ...so re-expand. */          buf_ptr[0] = ':';          buf_ptr[1] = ' ';          if (value->len)            {              apr_size_t vallen = value->len;              /* "$keyword: value $" */              if (vallen > (SVN_KEYWORD_MAX_LEN - 5))                vallen = SVN_KEYWORD_MAX_LEN - 5;              strncpy(buf_ptr + 2, value->data, vallen);              buf_ptr[2 + vallen] = ' ';              buf_ptr[2 + vallen + 1] = '$';              *len = 5 + keyword_len + vallen;            }          else            {              /* "$keyword: $"  */              buf_ptr[2] = '$';              *len = 4 + keyword_len;            }        }      return TRUE;    }    return FALSE;}                         /* Parse BUF (whose length is LEN, and which starts and ends with '$'),   trying to match one of the keyword names in KEYWORDS.  If such a   keyword is found, update *KEYWORD_NAME with the keyword name and   return TRUE. */static svn_boolean_tmatch_keyword(char *buf,              apr_size_t len,              char *keyword_name,              apr_hash_t *keywords){  apr_size_t i;  /* Early return for ignored keywords */  if (! keywords)    return FALSE;  /* Extract the name of the keyword */  for (i = 0; i < len - 2 && buf[i + 1] != ':'; i++)    keyword_name[i] = buf[i + 1];  keyword_name[i] = '\0';  return apr_hash_get(keywords, keyword_name, APR_HASH_KEY_STRING) != NULL;}/* Try to translate keyword *KEYWORD_NAME in BUF (whose length is LEN):   optionally perform the substitution in place, update *LEN with   the new length of the translated keyword string, and return TRUE.   If this buffer doesn't contain a known keyword pattern, leave BUF   and *LEN untouched and return FALSE.   See the docstring for svn_subst_copy_and_translate for how the   EXPAND and KEYWORDS parameters work.   NOTE: It is assumed that BUF has been allocated to be at least   SVN_KEYWORD_MAX_LEN bytes longs, and that the data in BUF is less   than or equal SVN_KEYWORD_MAX_LEN in length.  Also, any expansions   which would result in a keyword string which is greater than   SVN_KEYWORD_MAX_LEN will have their values truncated in such a way   that the resultant keyword string is still valid (begins with   "$Keyword:", ends in " $" and is SVN_KEYWORD_MAX_LEN bytes long).  */static svn_boolean_ttranslate_keyword(char *buf,                  apr_size_t *len,                  const char *keyword_name,                  svn_boolean_t expand,                  apr_hash_t *keywords){  const svn_string_t *value;  /* Make sure we gotz good stuffs. */  assert(*len <= SVN_KEYWORD_MAX_LEN);  assert((buf[0] == '$') && (buf[*len - 1] == '$'));  /* Early return for ignored keywords */  if (! keywords)    return FALSE;  value = apr_hash_get(keywords, keyword_name, APR_HASH_KEY_STRING);  if (value)    {      return translate_keyword_subst(buf, len,                                     keyword_name, strlen(keyword_name),                                     expand ? value : NULL);    }  return FALSE;}/* Translate NEWLINE_BUF (length of NEWLINE_LEN) to the newline format   specified in EOL_STR (length of EOL_STR_LEN), and write the   translated thing to FILE (whose path is DST_PATH).     SRC_FORMAT (length *SRC_FORMAT_LEN) is a cache of the first newline   found while processing SRC_PATH.  If the current newline is not the   same style as that of SRC_FORMAT, look to the REPAIR parameter.  If   REPAIR is TRUE, ignore the inconsistency, else return an   SVN_ERR_IO_INCONSISTENT_EOL error.  If we are examining the first   newline in the file, copy it to {SRC_FORMAT, *SRC_FORMAT_LEN} to   use for later consistency checks. */static svn_error_t *translate_newline(const char *eol_str,                  apr_size_t eol_str_len,                  char *src_format,                  apr_size_t *src_format_len,                  char *newline_buf,                  apr_size_t newline_len,                  svn_stream_t *dst,                  svn_boolean_t repair){  /* If this is the first newline we've seen, cache it     future comparisons, else compare it with our cache to     check for consistency. */  if (*src_format_len)    {      /* Comparing with cache.  If we are inconsistent and         we are NOT repairing the file, generate an error! */      if ((! repair) &&          ((*src_format_len != newline_len) ||           (strncmp(src_format, newline_buf, newline_len))))         return svn_error_create(SVN_ERR_IO_INCONSISTENT_EOL, NULL, NULL);    }  else    {      /* This is our first line ending, so cache it before         handling it. */      strncpy(src_format, newline_buf, newline_len);      *src_format_len = newline_len;    }  /* Translate the newline */  return translate_write(dst, eol_str, eol_str_len);}/*** Public interfaces. ***/svn_boolean_tsvn_subst_keywords_differ(const svn_subst_keywords_t *a,                          const svn_subst_keywords_t *b,                          svn_boolean_t compare_values){  if (((a == NULL) && (b == NULL)) /* no A or B */      /* no A, and B has no contents */      || ((a == NULL)           && (b->revision == NULL)          && (b->date == NULL)          && (b->author == NULL)          && (b->url == NULL))      /* no B, and A has no contents */      || ((b == NULL)           && (a->revision == NULL)          && (a->date == NULL)          && (a->author == NULL)          && (a->url == NULL))      /* neither A nor B has any contents */      || ((a != NULL) && (b != NULL)           && (b->revision == NULL)          && (b->date == NULL)          && (b->author == NULL)          && (b->url == NULL)          && (a->revision == NULL)          && (a->date == NULL)          && (a->author == NULL)          && (a->url == NULL)))    {      return FALSE;    }  else if ((a == NULL) || (b == NULL))    return TRUE;    /* Else both A and B have some keywords. */    if ((! a->revision) != (! b->revision))    return TRUE;  else if ((compare_values && (a->revision != NULL))           && (strcmp(a->revision->data, b->revision->data) != 0))    return TRUE;      if ((! a->date) != (! b->date))    return TRUE;  else if ((compare_values && (a->date != NULL))           && (strcmp(a->date->data, b->date->data) != 0))    return TRUE;      if ((! a->author) != (! b->author))    return TRUE;  else if ((compare_values && (a->author != NULL))           && (strcmp(a->author->data, b->author->data) != 0))    return TRUE;    if ((! a->url) != (! b->url))    return TRUE;  else if ((compare_values && (a->url != NULL))           && (strcmp(a->url->data, b->url->data) != 0))    return TRUE;    /* Else we never found a difference, so they must be the same. */      return FALSE;}svn_boolean_tsvn_subst_keywords_differ2(apr_hash_t *a,                           apr_hash_t *b,                           svn_boolean_t compare_values,                           apr_pool_t *pool){  apr_hash_index_t *hi;  unsigned int a_count, b_count;  /* An empty hash is logically equal to a NULL,   * as far as this API is concerned. */  a_count = (a == NULL) ? 0 : apr_hash_count(a);  b_count = (b == NULL) ? 0 : apr_hash_count(b);  if (a_count != b_count)    return TRUE;  if (a_count == 0)    return FALSE;  /* The hashes are both non-NULL, and have the same number of items.   * We must check that every item of A is present in B. */  for (hi = apr_hash_first(pool, a); hi; hi = apr_hash_next(hi))    {      const void *key;      apr_ssize_t klen;      void *void_a_val;      svn_string_t *a_val, *b_val;      apr_hash_this(hi, &key, &klen, &void_a_val);      a_val = void_a_val;      b_val = apr_hash_get(b, key, klen);      if (!b_val || (compare_values && !svn_string_compare(a_val, b_val)))        return TRUE;    }  return FALSE;}svn_error_t *svn_subst_translate_stream2(svn_stream_t *s, /* src stream */                            svn_stream_t *d, /* dst stream */                            const char *eol_str,                            svn_boolean_t repair,                            const svn_subst_keywords_t *keywords,                            svn_boolean_t expand,                            apr_pool_t *pool){  apr_hash_t *kh = kwstruct_to_kwhash(keywords, pool);  return svn_subst_translate_stream3(s, d, eol_str, repair, kh, expand, pool);}/* Baton for translate_chunk() to store its state in. */struct translation_baton{  const char *eol_str;  svn_boolean_t repair;  apr_hash_t *keywords;  svn_boolean_t expand;  /* Characters (excluding the terminating NUL character) which     may trigger a translation action, hence are 'interesting' */  const char *interesting;  /* Length of the string EOL_STR points to. */  apr_size_t eol_str_len;  /* Buffer to cache any newline state between translation chunks */  char newline_buf[2];  /* Offset (within newline_buf) of the first *unused* character */  apr_size_t newline_off;  /* Buffer to cache keyword-parsing state between translation chunks */  char keyword_buf[SVN_KEYWORD_MAX_LEN];  /* Offset (within keyword-buf) to the first *unused* character */  apr_size_t keyword_off;  /* EOL style used in the chunk-source */  char src_format[2];  /* Length of the EOL style string found in the chunk-source,     or zero if none encountered yet */  apr_size_t src_format_len;};/* Allocate a baton for use with translate_chunk() in POOL and * initialize it for the first iteration. * * The caller must assure that EOL_STR and KEYWORDS at least

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -