diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-08-05 16:22:51 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-08-05 16:22:51 +0000 |
commit | cf46733632c7279a9fd0fe6ce26f9185a4ae82a9 (patch) | |
tree | da27775a2161723ef342e91af41a8b51fedef405 /subversion/libsvn_subr/subst.c | |
parent | bb0ef45f7c46b0ae221b26265ef98a768c33f820 (diff) | |
download | subversion-tarball-master.tar.gz |
subversion-1.9.7HEADsubversion-1.9.7master
Diffstat (limited to 'subversion/libsvn_subr/subst.c')
-rw-r--r-- | subversion/libsvn_subr/subst.c | 100 |
1 files changed, 59 insertions, 41 deletions
diff --git a/subversion/libsvn_subr/subst.c b/subversion/libsvn_subr/subst.c index 223b269..388c31a 100644 --- a/subversion/libsvn_subr/subst.c +++ b/subversion/libsvn_subr/subst.c @@ -50,6 +50,7 @@ #include "svn_private_config.h" #include "private/svn_string_private.h" +#include "private/svn_eol_private.h" /** * The textual elements of a detranslated special file. One of these @@ -127,7 +128,7 @@ svn_subst_translation_required(svn_subst_eol_style_t style, * * 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 + * tolerance of NULL and zero inputs that that function's documentation * stipulates. * * The format codes: @@ -158,7 +159,7 @@ keyword_printf(const char *fmt, const char *author, apr_pool_t *pool) { - svn_stringbuf_t *value = svn_stringbuf_ncreate("", 0, pool); + svn_stringbuf_t *value = svn_stringbuf_create_empty(pool); const char *cur; size_t n; @@ -1122,28 +1123,42 @@ translate_chunk(svn_stream_t *dst, /* skip current EOL */ len += b->eol_str_len; - /* Check 4 bytes at once to allow for efficient pipelining - and to reduce loop condition overhead. */ - while ((p + len + 4) <= end) + if (b->keywords) { - if (interesting[(unsigned char)p[len]] - || interesting[(unsigned char)p[len+1]] - || interesting[(unsigned char)p[len+2]] - || interesting[(unsigned char)p[len+3]]) - break; - - len += 4; + /* Check 4 bytes at once to allow for efficient pipelining + and to reduce loop condition overhead. */ + while ((p + len + 4) <= end) + { + if (interesting[(unsigned char)p[len]] + || interesting[(unsigned char)p[len+1]] + || interesting[(unsigned char)p[len+2]] + || interesting[(unsigned char)p[len+3]]) + break; + + len += 4; + } + + /* Found an interesting char or EOF in the next 4 bytes. + Find its exact position. */ + while ((p + len) < end + && !interesting[(unsigned char)p[len]]) + ++len; } + else + { + /* use our optimized sub-routine to find the next EOL */ + const char *start = p + len; + const char *eol + = svn_eol__find_eol_start((char *)start, end - start); - /* Found an interesting char or EOF in the next 4 bytes. - Find its exact position. */ - while ((p + len) < end && !interesting[(unsigned char)p[len]]) - ++len; + /* EOL will be NULL if we did not find a line ending */ + len += (eol ? eol : end) - start; + } } while (b->nl_translation_skippable == svn_tristate_true && /* can potentially skip EOLs */ p + len + 2 < end && /* not too close to EOF */ - eol_unchanged (b, p + len)); /* EOL format already ok */ + eol_unchanged(b, p + len)); /* EOL format already ok */ while ((p + len) < end && !interesting[(unsigned char)p[len]]) len++; @@ -1276,7 +1291,7 @@ translated_stream_read(void *baton, svn_stringbuf_setempty(b->readbuf); b->readbuf_off = 0; - SVN_ERR(svn_stream_read(b->stream, b->buf, &readlen)); + SVN_ERR(svn_stream_read_full(b->stream, b->buf, &readlen)); buf_stream = svn_stream_from_stringbuf(b->readbuf, b->iterpool); SVN_ERR(translate_chunk(buf_stream, b->in_baton, b->buf, @@ -1527,7 +1542,8 @@ stream_translated(svn_stream_t *stream, baton->buf = apr_palloc(result_pool, SVN__TRANSLATION_BUF_SIZE); /* Setup the stream methods */ - svn_stream_set_read(s, translated_stream_read); + svn_stream_set_read2(s, NULL /* only full read support */, + translated_stream_read); svn_stream_set_write(s, translated_stream_write); svn_stream_set_close(s, translated_stream_close); svn_stream_set_mark(s, translated_stream_mark); @@ -1697,27 +1713,27 @@ create_special_file_from_stream(svn_stream_t *source, const char *dst, } /* If nothing else worked, write out the internal representation to - a file that can be edited by the user. - - ### this only writes the first line! - */ + a file that can be edited by the user. */ if (create_using_internal_representation) { - apr_file_t *new_file; - SVN_ERR(svn_io_open_unique_file3(&new_file, &dst_tmp, - svn_dirent_dirname(dst, pool), - svn_io_file_del_none, - pool, pool)); - - SVN_ERR(svn_io_file_write_full(new_file, - contents->data, contents->len, NULL, - pool)); - - SVN_ERR(svn_io_file_close(new_file, pool)); + svn_stream_t *new_stream; + apr_size_t len; + + SVN_ERR(svn_stream_open_unique(&new_stream, &dst_tmp, + svn_dirent_dirname(dst, pool), + svn_io_file_del_none, + pool, pool)); + + if (!eof) + svn_stringbuf_appendcstr(contents, "\n"); + len = contents->len; + SVN_ERR(svn_stream_write(new_stream, contents->data, &len)); + SVN_ERR(svn_stream_copy3(svn_stream_disown(source, pool), new_stream, + NULL, NULL, pool)); } /* Do the atomic rename from our temporary location. */ - return svn_io_file_rename(dst_tmp, dst, pool); + return svn_error_trace(svn_io_file_rename(dst_tmp, dst, pool)); } @@ -1765,8 +1781,9 @@ svn_subst_copy_and_translate4(const char *src, SVN_ERR(svn_stream_open_readonly(&src_stream, src, pool, pool)); } - return svn_error_trace(create_special_file_from_stream(src_stream, - dst, pool)); + SVN_ERR(create_special_file_from_stream(src_stream, dst, pool)); + + return svn_error_trace(svn_stream_close(src_stream)); } /* else !expand */ @@ -1835,10 +1852,10 @@ read_handler_special(void *baton, char *buffer, apr_size_t *len) if (btn->read_stream) /* We actually found a file to read from */ - return svn_stream_read(btn->read_stream, buffer, len); + return svn_stream_read_full(btn->read_stream, buffer, len); else return svn_error_createf(APR_ENOENT, NULL, - "Can't read special file: File '%s' not found", + _("Can't read special file: File '%s' not found"), svn_dirent_local_style(btn->path, btn->pool)); } @@ -1925,7 +1942,8 @@ svn_subst_stream_from_specialfile(svn_stream_t **stream, baton->write_stream = svn_stream_from_stringbuf(baton->write_content, pool); *stream = svn_stream_create(baton, pool); - svn_stream_set_read(*stream, read_handler_special); + svn_stream_set_read2(*stream, NULL /* only full read support */, + read_handler_special); svn_stream_set_write(*stream, write_handler_special); svn_stream_set_close(*stream, close_handler_special); @@ -1954,7 +1972,7 @@ svn_subst_translate_string2(svn_string_t **new_value, return SVN_NO_ERROR; } - if (encoding && !strcmp(encoding, "UTF-8")) + if (encoding && !strcmp(encoding, "UTF-8")) { val_utf8 = value->data; } |