a47ccee2ae
I will take the port OK per PM by Lev@
457 lines
17 KiB
Text
457 lines
17 KiB
Text
diff -ruN subversion/include/private/svn_subst_private.h subversion/include/private/svn_subst_private.h
|
||
--- subversion/include/private/svn_subst_private.h 1970-01-01 03:00:00.000000000 +0300
|
||
+++ subversion/include/private/svn_subst_private.h 2012-04-02 18:49:12.000000000 +0400
|
||
@@ -0,0 +1,68 @@
|
||
+/**
|
||
+ * @copyright
|
||
+ * ====================================================================
|
||
+ * Licensed to the Apache Software Foundation (ASF) under one
|
||
+ * or more contributor license agreements. See the NOTICE file
|
||
+ * distributed with this work for additional information
|
||
+ * regarding copyright ownership. The ASF licenses this file
|
||
+ * to you under the Apache License, Version 2.0 (the
|
||
+ * "License"); you may not use this file except in compliance
|
||
+ * with the License. You may obtain a copy of the License at
|
||
+ *
|
||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||
+ *
|
||
+ * Unless required by applicable law or agreed to in writing,
|
||
+ * software distributed under the License is distributed on an
|
||
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
+ * KIND, either express or implied. See the License for the
|
||
+ * specific language governing permissions and limitations
|
||
+ * under the License.
|
||
+ * ====================================================================
|
||
+ * @endcopyright
|
||
+ *
|
||
+ * @file svn_subst_private.h
|
||
+ * @brief Non-public subst utility functions.
|
||
+ */
|
||
+
|
||
+
|
||
+#ifndef SVN_SUBST_PRIVATE_H
|
||
+#define SVN_SUBST_PRIVATE_H
|
||
+
|
||
+#include "svn_subst.h" /* for svn_boolean_t, svn_error_t */
|
||
+
|
||
+#ifdef __cplusplus
|
||
+extern "C" {
|
||
+#endif /* __cplusplus */
|
||
+
|
||
+/**
|
||
+ * Set @a *kw to a new keywords hash filled with the appropriate contents
|
||
+ * given a @a keywords_string (the contents of the svn:keywords
|
||
+ * property for the file in question), the revision @a rev, the @a url,
|
||
+ * the url of the root of the @a repos, the @a date the file was committed
|
||
+ * on, and the @a author of the last commit. Any of these can be @c NULL
|
||
+ * to indicate that the information is not present, or @c 0 for @a date.
|
||
+ *
|
||
+ * Hash keys are of type <tt>const char *</tt>.
|
||
+ * Hash values are of type <tt>svn_string_t *</tt>.
|
||
+ *
|
||
+ * All memory is allocated out of @a pool.
|
||
+ *
|
||
+ * @since New in 1.6
|
||
+ */
|
||
+svn_error_t *
|
||
+svn_subst_build_keywords3(apr_hash_t **kw,
|
||
+ const char *keywords_string,
|
||
+ const char *rev,
|
||
+ const char *url,
|
||
+ const char *repos,
|
||
+ apr_time_t date,
|
||
+ const char *author,
|
||
+ apr_pool_t *pool);
|
||
+
|
||
+
|
||
+
|
||
+#ifdef __cplusplus
|
||
+}
|
||
+#endif /* __cplusplus */
|
||
+
|
||
+#endif /* SVN_SUBST_PRIVATE_H */
|
||
diff -ruN subversion/libsvn_client/cat.c subversion/libsvn_client/cat.c
|
||
--- subversion/libsvn_client/cat.c 2011-08-18 18:05:35.000000000 +0400
|
||
+++ subversion/libsvn_client/cat.c 2012-04-02 18:46:56.000000000 +0400
|
||
@@ -40,6 +40,7 @@
|
||
|
||
#include "svn_private_config.h"
|
||
#include "private/svn_wc_private.h"
|
||
+#include "private/svn_subst_private.h"
|
||
|
||
|
||
/*** Code. ***/
|
||
@@ -137,12 +138,15 @@
|
||
const char *rev_str;
|
||
const char *author;
|
||
const char *url;
|
||
+ const char *repos;
|
||
|
||
SVN_ERR(svn_wc__node_get_changed_info(&changed_rev, NULL, &author, wc_ctx,
|
||
local_abspath, scratch_pool,
|
||
scratch_pool));
|
||
SVN_ERR(svn_wc__node_get_url(&url, wc_ctx, local_abspath, scratch_pool,
|
||
scratch_pool));
|
||
+ SVN_ERR(svn_wc__node_get_repos_info(&repos, NULL, wc_ctx, local_abspath,
|
||
+ scratch_pool, scratch_pool));
|
||
|
||
if (local_mod)
|
||
{
|
||
@@ -158,8 +162,8 @@
|
||
rev_str = apr_psprintf(scratch_pool, "%ld", changed_rev);
|
||
}
|
||
|
||
- SVN_ERR(svn_subst_build_keywords2(&kw, keywords->data, rev_str, url, tm,
|
||
- author, scratch_pool));
|
||
+ SVN_ERR(svn_subst_build_keywords3(&kw, keywords->data, rev_str, url,
|
||
+ repos, tm, author, scratch_pool));
|
||
}
|
||
|
||
/* Wrap the output stream if translation is needed. */
|
||
@@ -188,6 +192,7 @@
|
||
svn_string_t *keywords;
|
||
apr_hash_t *props;
|
||
const char *url;
|
||
+ const char *repos_root_url;
|
||
svn_stream_t *output = out;
|
||
svn_error_t *err;
|
||
|
||
@@ -231,6 +236,8 @@
|
||
&url, path_or_url, NULL,
|
||
peg_revision,
|
||
revision, ctx, pool));
|
||
+ /* Find the repos root URL */
|
||
+ SVN_ERR(svn_ra_get_repos_root2(ra_session, &repos_root_url, pool));
|
||
|
||
/* Grab some properties we need to know in order to figure out if anything
|
||
special needs to be done with this file. */
|
||
@@ -281,10 +288,11 @@
|
||
if (cmt_date)
|
||
SVN_ERR(svn_time_from_cstring(&when, cmt_date->data, pool));
|
||
|
||
- SVN_ERR(svn_subst_build_keywords2
|
||
+ SVN_ERR(svn_subst_build_keywords3
|
||
(&kw, keywords->data,
|
||
cmt_rev->data,
|
||
url,
|
||
+ repos_root_url,
|
||
when,
|
||
cmt_author ? cmt_author->data : NULL,
|
||
pool));
|
||
diff -ruN subversion/libsvn_client/commit.c subversion/libsvn_client/commit.c
|
||
--- subversion/libsvn_client/commit.c 2011-11-28 21:04:12.000000000 +0400
|
||
+++ subversion/libsvn_client/commit.c 2012-04-02 18:46:52.000000000 +0400
|
||
@@ -50,6 +50,7 @@
|
||
#include "client.h"
|
||
#include "private/svn_wc_private.h"
|
||
#include "private/svn_magic.h"
|
||
+#include "private/svn_subst_private.h"
|
||
|
||
#include "svn_private_config.h"
|
||
|
||
@@ -126,9 +127,9 @@
|
||
}
|
||
|
||
if (keywords_val)
|
||
- SVN_ERR(svn_subst_build_keywords2(&keywords, keywords_val->data,
|
||
+ SVN_ERR(svn_subst_build_keywords3(&keywords, keywords_val->data,
|
||
APR_STRINGIFY(SVN_INVALID_REVNUM),
|
||
- "", 0, "", pool));
|
||
+ "", "", 0, "", pool));
|
||
else
|
||
keywords = NULL;
|
||
|
||
diff -ruN subversion/libsvn_client/export.c subversion/libsvn_client/export.c
|
||
--- subversion/libsvn_client/export.c 2012-02-10 08:00:30.000000000 +0400
|
||
+++ subversion/libsvn_client/export.c 2012-04-02 18:46:47.000000000 +0400
|
||
@@ -43,6 +43,7 @@
|
||
|
||
#include "svn_private_config.h"
|
||
#include "private/svn_wc_private.h"
|
||
+#include "private/svn_subst_private.h"
|
||
|
||
|
||
/*** Code. ***/
|
||
@@ -274,6 +275,7 @@
|
||
svn_revnum_t changed_rev;
|
||
const char *suffix;
|
||
const char *url;
|
||
+ const char *repos;
|
||
const char *author;
|
||
|
||
SVN_ERR(svn_wc__node_get_changed_info(&changed_rev, NULL, &author,
|
||
@@ -296,11 +298,13 @@
|
||
|
||
SVN_ERR(svn_wc__node_get_url(&url, wc_ctx, from_abspath,
|
||
scratch_pool, scratch_pool));
|
||
+ SVN_ERR(svn_wc__node_get_repos_info(&repos, NULL, wc_ctx, from_abspath,
|
||
+ scratch_pool, scratch_pool));
|
||
|
||
- SVN_ERR(svn_subst_build_keywords2
|
||
+ SVN_ERR(svn_subst_build_keywords3
|
||
(&kw, keywords->data,
|
||
apr_psprintf(scratch_pool, "%ld%s", changed_rev, suffix),
|
||
- url, tm, author, scratch_pool));
|
||
+ url, repos, tm, author, scratch_pool));
|
||
}
|
||
|
||
/* For atomicity, we translate to a tmp file and then rename the tmp file
|
||
@@ -702,6 +706,7 @@
|
||
/* Any keyword vals to be substituted */
|
||
const char *revision;
|
||
const char *url;
|
||
+ const char *repos;
|
||
const char *author;
|
||
apr_time_t date;
|
||
|
||
@@ -823,6 +828,7 @@
|
||
fb->edit_baton = eb;
|
||
fb->path = full_path;
|
||
fb->url = full_url;
|
||
+ fb->repos = eb->root_url;
|
||
fb->pool = pool;
|
||
|
||
*baton = fb;
|
||
@@ -987,8 +993,8 @@
|
||
}
|
||
|
||
if (fb->keywords_val)
|
||
- SVN_ERR(svn_subst_build_keywords2(&final_kw, fb->keywords_val->data,
|
||
- fb->revision, fb->url, fb->date,
|
||
+ SVN_ERR(svn_subst_build_keywords3(&final_kw, fb->keywords_val->data,
|
||
+ fb->revision, fb->url, fb->repos, fb->date,
|
||
fb->author, pool));
|
||
|
||
SVN_ERR(svn_subst_copy_and_translate4(fb->tmppath, fb->path,
|
||
diff -ruN subversion/libsvn_subr/subst.c subversion/libsvn_subr/subst.c
|
||
--- subversion/libsvn_subr/subst.c 2011-07-29 21:28:11.000000000 +0400
|
||
+++ subversion/libsvn_subr/subst.c 2012-04-02 18:47:06.000000000 +0400
|
||
@@ -49,6 +49,7 @@
|
||
#include "svn_private_config.h"
|
||
|
||
#include "private/svn_string_private.h"
|
||
+#include "private/svn_subst_private.h"
|
||
|
||
/**
|
||
* The textual elements of a detranslated special file. One of these
|
||
@@ -135,8 +136,11 @@
|
||
* %b basename of the URL of this file
|
||
* %d short format of date of this revision
|
||
* %D long format of date of this revision
|
||
+ * %P path relative to root of repos
|
||
* %r number of this revision
|
||
+ * %R root url of repository
|
||
* %u URL of this file
|
||
+ * %_ a space
|
||
* %% a literal %
|
||
*
|
||
* All memory is allocated out of @a pool.
|
||
@@ -145,12 +149,14 @@
|
||
keyword_printf(const char *fmt,
|
||
const char *rev,
|
||
const char *url,
|
||
+ const char *repos,
|
||
apr_time_t date,
|
||
const char *author,
|
||
apr_pool_t *pool)
|
||
{
|
||
svn_stringbuf_t *value = svn_stringbuf_ncreate("", 0, pool);
|
||
const char *cur;
|
||
+ const char *relative;
|
||
size_t n;
|
||
|
||
for (;;)
|
||
@@ -203,6 +209,23 @@
|
||
svn_stringbuf_appendcstr(value,
|
||
svn_time_to_human_cstring(date, pool));
|
||
break;
|
||
+ case 'P': /* relative path of this file */
|
||
+ relative = url;
|
||
+ if (relative && repos)
|
||
+ {
|
||
+ int len = strlen(repos);
|
||
+
|
||
+ if (strncmp(repos, relative, len) == 0
|
||
+ && relative[len] == '/')
|
||
+ relative += len + 1;
|
||
+ }
|
||
+ if (relative)
|
||
+ svn_stringbuf_appendcstr(value, relative);
|
||
+ break;
|
||
+ case 'R': /* root of repos */
|
||
+ if (repos)
|
||
+ svn_stringbuf_appendcstr(value, repos);
|
||
+ break;
|
||
case 'r': /* number of this revision */
|
||
if (rev)
|
||
svn_stringbuf_appendcstr(value, rev);
|
||
@@ -211,6 +234,9 @@
|
||
if (url)
|
||
svn_stringbuf_appendcstr(value, url);
|
||
break;
|
||
+ case '_': /* '%_' => a space */
|
||
+ svn_stringbuf_appendbytes(value, " ", 1);
|
||
+ break;
|
||
case '%': /* '%%' => a literal % */
|
||
svn_stringbuf_appendbyte(value, *cur);
|
||
break;
|
||
@@ -246,8 +272,8 @@
|
||
apr_hash_t *kwhash;
|
||
const svn_string_t *val;
|
||
|
||
- SVN_ERR(svn_subst_build_keywords2(&kwhash, keywords_val, rev,
|
||
- url, date, author, pool));
|
||
+ SVN_ERR(svn_subst_build_keywords3(&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
|
||
@@ -286,6 +312,21 @@
|
||
const char *author,
|
||
apr_pool_t *pool)
|
||
{
|
||
+ SVN_ERR(svn_subst_build_keywords3(kw, keywords_val, rev,
|
||
+ url, "", date, author, pool));
|
||
+ return SVN_NO_ERROR;
|
||
+}
|
||
+
|
||
+svn_error_t *
|
||
+svn_subst_build_keywords3(apr_hash_t **kw,
|
||
+ const char *keywords_val,
|
||
+ const char *rev,
|
||
+ const char *url,
|
||
+ const char *repos,
|
||
+ apr_time_t date,
|
||
+ const char *author,
|
||
+ apr_pool_t *pool)
|
||
+{
|
||
apr_array_header_t *keyword_tokens;
|
||
int i;
|
||
*kw = apr_hash_make(pool);
|
||
@@ -296,6 +337,24 @@
|
||
for (i = 0; i < keyword_tokens->nelts; ++i)
|
||
{
|
||
const char *keyword = APR_ARRAY_IDX(keyword_tokens, i, const char *);
|
||
+ apr_array_header_t *keyword_tokens2;
|
||
+
|
||
+ keyword_tokens2 = svn_cstring_split(keyword, "=", TRUE /* chop */, pool);
|
||
+ if (keyword_tokens2->nelts == 2)
|
||
+ {
|
||
+ svn_string_t *custom_val;
|
||
+ const char *custom_expand;
|
||
+
|
||
+ keyword = APR_ARRAY_IDX(keyword_tokens2, 0, const char*);
|
||
+ custom_expand = APR_ARRAY_IDX(keyword_tokens2, 1, const char*);
|
||
+ if (! strcmp(custom_expand, "%H"))
|
||
+ custom_expand = "%P %r %d %a";
|
||
+ else if (! strcmp(custom_expand, "%I"))
|
||
+ custom_expand = "%b %r %d %a";
|
||
+ custom_val = keyword_printf(custom_expand, rev, url, repos, date, author, pool);
|
||
+ apr_hash_set(*kw, keyword, APR_HASH_KEY_STRING, custom_val);
|
||
+ return SVN_NO_ERROR;
|
||
+ }
|
||
|
||
if ((! strcmp(keyword, SVN_KEYWORD_REVISION_LONG))
|
||
|| (! strcmp(keyword, SVN_KEYWORD_REVISION_MEDIUM))
|
||
@@ -303,7 +362,7 @@
|
||
{
|
||
svn_string_t *revision_val;
|
||
|
||
- revision_val = keyword_printf("%r", rev, url, date, author, pool);
|
||
+ revision_val = keyword_printf("%r", rev, url, repos, 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,
|
||
@@ -316,7 +375,7 @@
|
||
{
|
||
svn_string_t *date_val;
|
||
|
||
- date_val = keyword_printf("%D", rev, url, date, author, pool);
|
||
+ date_val = keyword_printf("%D", rev, url, repos, 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,
|
||
@@ -327,7 +386,7 @@
|
||
{
|
||
svn_string_t *author_val;
|
||
|
||
- author_val = keyword_printf("%a", rev, url, date, author, pool);
|
||
+ author_val = keyword_printf("%a", rev, url, repos, 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,
|
||
@@ -338,7 +397,7 @@
|
||
{
|
||
svn_string_t *url_val;
|
||
|
||
- url_val = keyword_printf("%u", rev, url, date, author, pool);
|
||
+ url_val = keyword_printf("%u", rev, url, repos, 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,
|
||
@@ -348,7 +407,7 @@
|
||
{
|
||
svn_string_t *id_val;
|
||
|
||
- id_val = keyword_printf("%b %r %d %a", rev, url, date, author,
|
||
+ id_val = keyword_printf("%b %r %d %a", rev, url, repos, date, author,
|
||
pool);
|
||
apr_hash_set(*kw, SVN_KEYWORD_ID,
|
||
APR_HASH_KEY_STRING, id_val);
|
||
@@ -357,7 +416,7 @@
|
||
{
|
||
svn_string_t *header_val;
|
||
|
||
- header_val = keyword_printf("%u %r %d %a", rev, url, date, author,
|
||
+ header_val = keyword_printf("%u %r %d %a", rev, url, repos, date, author,
|
||
pool);
|
||
apr_hash_set(*kw, SVN_KEYWORD_HEADER,
|
||
APR_HASH_KEY_STRING, header_val);
|
||
diff -ruN subversion/libsvn_wc/translate.c subversion/libsvn_wc/translate.c
|
||
--- subversion/libsvn_wc/translate.c 2011-07-07 15:29:08.000000000 +0400
|
||
+++ subversion/libsvn_wc/translate.c 2012-04-02 18:47:00.000000000 +0400
|
||
@@ -46,6 +46,7 @@
|
||
|
||
#include "svn_private_config.h"
|
||
#include "private/svn_wc_private.h"
|
||
+#include "private/svn_subst_private.h"
|
||
|
||
|
||
|
||
@@ -313,10 +314,10 @@
|
||
apr_time_t changed_date;
|
||
const char *changed_author;
|
||
const char *url;
|
||
+ const char *repos_root_url;
|
||
|
||
if (! for_normalization)
|
||
{
|
||
- const char *repos_root_url;
|
||
const char *repos_relpath;
|
||
|
||
SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, &repos_relpath,
|
||
@@ -341,13 +342,23 @@
|
||
changed_rev = SVN_INVALID_REVNUM;
|
||
changed_date = 0;
|
||
changed_author = "";
|
||
+
|
||
+ SVN_ERR(svn_wc__db_read_info(NULL, NULL, NULL, NULL,
|
||
+ &repos_root_url, NULL, NULL,
|
||
+ NULL, NULL, NULL,
|
||
+ NULL, NULL, NULL, NULL, NULL, NULL,
|
||
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||
+ NULL, NULL, NULL, NULL,
|
||
+ db, local_abspath,
|
||
+ scratch_pool, scratch_pool));
|
||
}
|
||
|
||
- SVN_ERR(svn_subst_build_keywords2(keywords,
|
||
+ SVN_ERR(svn_subst_build_keywords3(keywords,
|
||
keyword_list,
|
||
apr_psprintf(scratch_pool, "%ld",
|
||
changed_rev),
|
||
url,
|
||
+ repos_root_url,
|
||
changed_date,
|
||
changed_author,
|
||
result_pool));
|