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

📄 subst.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * subst.c :  generic eol/keyword substitution routines * * ==================================================================== * Copyright (c) 2000-2006 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#define APR_WANT_STRFUNC#include <apr_want.h>#include <stdlib.h>#include <assert.h>#include <apr_general.h>  /* for strcasecmp() */#include <apr_pools.h>#include <apr_tables.h>#include <apr_file_io.h>#include <apr_strings.h>#include "svn_cmdline.h"#include "svn_types.h"#include "svn_string.h"#include "svn_time.h"#include "svn_path.h"#include "svn_error.h"#include "svn_utf.h"#include "svn_io.h"#include "svn_subst.h"#include "svn_pools.h"#include "svn_private_config.h"/* The Repository Default EOL used for files which * use the 'native' eol style. */#define SVN_SUBST__DEFAULT_EOL_STR "\n"/** * The textual elements of a detranslated special file.  One of these * strings must appear as the first element of any special file as it * exists in the repository or the text base. */#define SVN_SUBST__SPECIAL_LINK_STR "link"void svn_subst_eol_style_from_value(svn_subst_eol_style_t *style,                               const char **eol,                               const char *value){  if (value == NULL)    {      /* property doesn't exist. */      *eol = NULL;      if (style)        *style = svn_subst_eol_style_none;    }  else if (! strcmp("native", value))    {      *eol = APR_EOL_STR;       /* whee, a portability library! */      if (style)        *style = svn_subst_eol_style_native;    }  else if (! strcmp("LF", value))    {      *eol = "\n";      if (style)        *style = svn_subst_eol_style_fixed;    }  else if (! strcmp("CR", value))    {      *eol = "\r";      if (style)        *style = svn_subst_eol_style_fixed;    }  else if (! strcmp("CRLF", value))    {      *eol = "\r\n";      if (style)        *style = svn_subst_eol_style_fixed;    }  else    {      *eol = NULL;      if (style)        *style = svn_subst_eol_style_unknown;    }}svn_boolean_tsvn_subst_translation_required(svn_subst_eol_style_t style,                               const char *eol,                               apr_hash_t *keywords,                               svn_boolean_t special,                               svn_boolean_t force_eol_check){  return (special || keywords          || (style != svn_subst_eol_style_none && force_eol_check)          || (style == svn_subst_eol_style_native &&              strcmp(APR_EOL_STR, SVN_SUBST__DEFAULT_EOL_STR) != 0)          || (style == svn_subst_eol_style_fixed &&              strcmp(APR_EOL_STR, eol) != 0));}svn_error_t *svn_subst_translate_to_normal_form(const char *src,                                   const char *dst,                                   svn_subst_eol_style_t eol_style,                                   const char *eol_str,                                   svn_boolean_t always_repair_eols,                                   apr_hash_t *keywords,                                   svn_boolean_t special,                                   apr_pool_t *pool){  if (eol_style == svn_subst_eol_style_native)    eol_str = SVN_SUBST__DEFAULT_EOL_STR;  else if (! (eol_style == svn_subst_eol_style_fixed              || eol_style == svn_subst_eol_style_none))    return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);  return svn_subst_copy_and_translate3(src, dst, eol_str,                                       eol_style == svn_subst_eol_style_fixed                                       || always_repair_eols,                                       keywords,                                       FALSE /* contract keywords */,                                       special,                                       pool);}/* Helper function for svn_subst_build_keywords *//* Given a printf-like format string, return a string with proper * information filled in. * * Important API note: This function is the core of the implementation of * svn_subst_build_keywords (all versions), and as such must implement the * tolerance of NULL and zero inputs that that function's documention * stipulates. * * The format codes: * * %a author of this revision * %b basename of the URL of this file * %d short format of date of this revision * %D long format of date of this revision * %r number of this revision * %u URL of this file * %% a literal % * * All memory is allocated out of @a pool. */static svn_string_t *keyword_printf(const char *fmt,               const char *rev,               const char *url,               apr_time_t date,               const char *author,               apr_pool_t *pool){  svn_stringbuf_t *value = svn_stringbuf_ncreate("", 0, pool);  const char *cur;  int n;  for (;;)    {      cur = fmt;      while (*cur != '\0' && *cur != '%')        cur++;      if ((n = cur - fmt) > 0) /* Do we have an as-is string? */        svn_stringbuf_appendbytes(value, fmt, n);      if (*cur == '\0')        break;      switch (cur[1])        {        case 'a': /* author of this revision */          if (author)            svn_stringbuf_appendcstr(value, author);          break;        case 'b': /* basename of this file */          if (url)            {              const char *base_name                = svn_path_uri_decode(svn_path_basename(url, pool), pool);              svn_stringbuf_appendcstr(value, base_name);            }          break;        case 'd': /* short format of date of this revision */          if (date)            {              apr_time_exp_t exploded_time;              const char *human;              apr_time_exp_gmt(&exploded_time, date);              human = apr_psprintf(pool, "%04d-%02d-%02d %02d:%02d:%02dZ",                                   exploded_time.tm_year + 1900,                                   exploded_time.tm_mon + 1,                                   exploded_time.tm_mday,                                   exploded_time.tm_hour,                                   exploded_time.tm_min,                                   exploded_time.tm_sec);              svn_stringbuf_appendcstr(value, human);            }          break;        case 'D': /* long format of date of this revision */          if (date)            svn_stringbuf_appendcstr(value,                                     svn_time_to_human_cstring(date, pool));          break;        case 'r': /* number of this revision */          if (rev)            svn_stringbuf_appendcstr(value, rev);          break;        case 'u': /* URL of this file */          if (url)            svn_stringbuf_appendcstr(value, url);          break;        case '%': /* '%%' => a literal % */          svn_stringbuf_appendbytes(value, cur, 1);          break;        case '\0': /* '%' as the last character of the string. */          svn_stringbuf_appendbytes(value, cur, 1);          /* Now go back one character, since this was just a one character           * sequence, whereas all others are two characters, and we do not           * want to skip the null terminator entirely and carry on           * formatting random memory contents. */          cur--;          break;        default: /* Unrecognized code, just print it literally. */          svn_stringbuf_appendbytes(value, cur, 2);          break;        }      /* Format code is processed - skip it, and get ready for next chunk. */      fmt = cur + 2;    }  return svn_string_create_from_buf(value, pool);}/* Convert an old-style svn_subst_keywords_t struct * into a new-style * keywords hash.  Keyword values are shallow copies, so the produced * hash must not be assumed to have lifetime longer than the struct it * is based on.  A NULL input causes a NULL output. */static apr_hash_t *kwstruct_to_kwhash(const svn_subst_keywords_t *kwstruct,                   apr_pool_t *pool){  apr_hash_t *kwhash;  if (kwstruct == NULL)    return NULL;  kwhash = apr_hash_make(pool);  if (kwstruct->revision)    {      apr_hash_set(kwhash, SVN_KEYWORD_REVISION_LONG,                   APR_HASH_KEY_STRING, kwstruct->revision);      apr_hash_set(kwhash, SVN_KEYWORD_REVISION_MEDIUM,                   APR_HASH_KEY_STRING, kwstruct->revision);      apr_hash_set(kwhash, SVN_KEYWORD_REVISION_SHORT,                   APR_HASH_KEY_STRING, kwstruct->revision);    }  if (kwstruct->date)    {      apr_hash_set(kwhash, SVN_KEYWORD_DATE_LONG,                   APR_HASH_KEY_STRING, kwstruct->date);      apr_hash_set(kwhash, SVN_KEYWORD_DATE_SHORT,                   APR_HASH_KEY_STRING, kwstruct->date);    }  if (kwstruct->author)    {      apr_hash_set(kwhash, SVN_KEYWORD_AUTHOR_LONG,                   APR_HASH_KEY_STRING, kwstruct->author);      apr_hash_set(kwhash, SVN_KEYWORD_AUTHOR_SHORT,                   APR_HASH_KEY_STRING, kwstruct->author);    }  if (kwstruct->url)    {      apr_hash_set(kwhash, SVN_KEYWORD_URL_LONG,                   APR_HASH_KEY_STRING, kwstruct->url);      apr_hash_set(kwhash, SVN_KEYWORD_URL_SHORT,                   APR_HASH_KEY_STRING, kwstruct->url);    }  if (kwstruct->id)    {      apr_hash_set(kwhash, SVN_KEYWORD_ID,                   APR_HASH_KEY_STRING, kwstruct->id);    }  return kwhash;}svn_error_t *svn_subst_build_keywords(svn_subst_keywords_t *kw,                         const char *keywords_val,                         const char *rev,                         const char *url,                         apr_time_t date,                         const char *author,                         apr_pool_t *pool){  apr_hash_t *kwhash;  const svn_string_t *val;  SVN_ERR(svn_subst_build_keywords2(&kwhash, keywords_val, rev,                                    url, date, author, pool));  /* The behaviour of pre-1.3 svn_subst_build_keywords, which we are   * replicating here, is to write to a slot in the svn_subst_keywords_t   * only if the relevant keyword was present in keywords_val, otherwise   * leaving that slot untouched. */  val = apr_hash_get(kwhash, SVN_KEYWORD_REVISION_LONG, APR_HASH_KEY_STRING);  if (val)    kw->revision = val;  val = apr_hash_get(kwhash, SVN_KEYWORD_DATE_LONG, APR_HASH_KEY_STRING);  if (val)    kw->date = val;  val = apr_hash_get(kwhash, SVN_KEYWORD_AUTHOR_LONG, APR_HASH_KEY_STRING);  if (val)    kw->author = val;  val = apr_hash_get(kwhash, SVN_KEYWORD_URL_LONG, APR_HASH_KEY_STRING);  if (val)    kw->url = val;  val = apr_hash_get(kwhash, SVN_KEYWORD_ID, APR_HASH_KEY_STRING);  if (val)    kw->id = val;  return SVN_NO_ERROR;}svn_error_t *svn_subst_build_keywords2(apr_hash_t **kw,                          const char *keywords_val,                          const char *rev,                          const char *url,                          apr_time_t date,                          const char *author,                          apr_pool_t *pool){  apr_array_header_t *keyword_tokens;  int i;  *kw = apr_hash_make(pool);  keyword_tokens = svn_cstring_split(keywords_val, " \t\v\n\b\r\f",                                     TRUE /* chop */, pool);  for (i = 0; i < keyword_tokens->nelts; ++i)    {      const char *keyword = APR_ARRAY_IDX(keyword_tokens, i, const char *);      if ((! strcmp(keyword, SVN_KEYWORD_REVISION_LONG))          || (! strcmp(keyword, SVN_KEYWORD_REVISION_MEDIUM))          || (! strcasecmp(keyword, SVN_KEYWORD_REVISION_SHORT)))        {          svn_string_t *revision_val;          revision_val = keyword_printf("%r", rev, url, date, author, pool);          apr_hash_set(*kw, SVN_KEYWORD_REVISION_LONG,                       APR_HASH_KEY_STRING, revision_val);          apr_hash_set(*kw, SVN_KEYWORD_REVISION_MEDIUM,                       APR_HASH_KEY_STRING, revision_val);          apr_hash_set(*kw, SVN_KEYWORD_REVISION_SHORT,                       APR_HASH_KEY_STRING, revision_val);        }      else if ((! strcmp(keyword, SVN_KEYWORD_DATE_LONG))               || (! strcasecmp(keyword, SVN_KEYWORD_DATE_SHORT)))        {          svn_string_t *date_val;          date_val = keyword_printf("%D", rev, url, date, author, pool);          apr_hash_set(*kw, SVN_KEYWORD_DATE_LONG,                       APR_HASH_KEY_STRING, date_val);          apr_hash_set(*kw, SVN_KEYWORD_DATE_SHORT,                       APR_HASH_KEY_STRING, date_val);        }      else if ((! strcmp(keyword, SVN_KEYWORD_AUTHOR_LONG))               || (! strcasecmp(keyword, SVN_KEYWORD_AUTHOR_SHORT)))        {          svn_string_t *author_val;          author_val = keyword_printf("%a", rev, url, date, author, pool);          apr_hash_set(*kw, SVN_KEYWORD_AUTHOR_LONG,                       APR_HASH_KEY_STRING, author_val);          apr_hash_set(*kw, SVN_KEYWORD_AUTHOR_SHORT,                       APR_HASH_KEY_STRING, author_val);        }      else if ((! strcmp(keyword, SVN_KEYWORD_URL_LONG))               || (! strcasecmp(keyword, SVN_KEYWORD_URL_SHORT)))        {          svn_string_t *url_val;          url_val = keyword_printf("%u", rev, url, date, author, pool);          apr_hash_set(*kw, SVN_KEYWORD_URL_LONG,                       APR_HASH_KEY_STRING, url_val);          apr_hash_set(*kw, SVN_KEYWORD_URL_SHORT,                       APR_HASH_KEY_STRING, url_val);        }      else if ((! strcasecmp(keyword, SVN_KEYWORD_ID)))        {          svn_string_t *id_val;          id_val = keyword_printf("%b %r %d %a", rev, url, date, author,                                  pool);          apr_hash_set(*kw, SVN_KEYWORD_ID,                       APR_HASH_KEY_STRING, id_val);        }    }  return SVN_NO_ERROR;}/*** Helpers for svn_subst_translate_stream2 ***//* Write out LEN bytes of BUF into STREAM. */

⌨️ 快捷键说明

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