📄 subst.c
字号:
baton->buf = apr_palloc(baton->pool, SVN__STREAM_CHUNK_SIZE + 1); /* Setup the stream methods */ svn_stream_set_read(s, translated_stream_read); svn_stream_set_write(s, translated_stream_write); svn_stream_set_close(s, translated_stream_close); return s;}svn_error_t *svn_subst_translate_stream3(svn_stream_t *s, /* src stream */ svn_stream_t *d, /* dst stream */ const char *eol_str, svn_boolean_t repair, apr_hash_t *keywords, svn_boolean_t expand, apr_pool_t *pool){ apr_pool_t *subpool = svn_pool_create(pool); apr_pool_t *iterpool = svn_pool_create(subpool); struct translation_baton *baton; apr_size_t readlen = SVN__STREAM_CHUNK_SIZE; char *buf = apr_palloc(subpool, SVN__STREAM_CHUNK_SIZE); /* The docstring requires that *some* translation be requested. */ assert(eol_str || keywords); baton = create_translation_baton(eol_str, repair, keywords, expand, pool); while (readlen == SVN__STREAM_CHUNK_SIZE) { svn_pool_clear(iterpool); SVN_ERR(svn_stream_read(s, buf, &readlen)); SVN_ERR(translate_chunk(d, baton, buf, readlen, iterpool)); } SVN_ERR(translate_chunk(d, baton, NULL, 0, iterpool)); svn_pool_destroy(subpool); /* also destroys iterpool */ return SVN_NO_ERROR;}svn_error_t *svn_subst_translate_stream(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 = svn_pool_create(NULL); svn_error_t *err = svn_subst_translate_stream2(s, d, eol_str, repair, keywords, expand, pool); svn_pool_destroy(pool); return err;}svn_error_t *svn_subst_translate_cstring(const char *src, const char **dst, 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_cstring2(src, dst, eol_str, repair, kh, expand, pool);}svn_error_t *svn_subst_translate_cstring2(const char *src, const char **dst, const char *eol_str, svn_boolean_t repair, apr_hash_t *keywords, svn_boolean_t expand, apr_pool_t *pool){ svn_stringbuf_t *src_stringbuf, *dst_stringbuf; svn_stream_t *src_stream, *dst_stream; svn_error_t *err; src_stringbuf = svn_stringbuf_create(src, pool); /* The easy way out: no translation needed, just copy. */ if (! (eol_str || (keywords && (apr_hash_count(keywords) > 0)))) { dst_stringbuf = svn_stringbuf_dup(src_stringbuf, pool); goto all_good; } /* Convert our stringbufs into streams. */ src_stream = svn_stream_from_stringbuf(src_stringbuf, pool); dst_stringbuf = svn_stringbuf_create("", pool); dst_stream = svn_stream_from_stringbuf(dst_stringbuf, pool); /* Translate src stream into dst stream. */ err = svn_subst_translate_stream3(src_stream, dst_stream, eol_str, repair, keywords, expand, pool); if (err) { svn_error_clear(svn_stream_close(src_stream)); svn_error_clear(svn_stream_close(dst_stream)); return err; } /* clean up nicely. */ SVN_ERR(svn_stream_close(src_stream)); SVN_ERR(svn_stream_close(dst_stream)); all_good: *dst = dst_stringbuf->data; return SVN_NO_ERROR;}svn_error_t *svn_subst_copy_and_translate(const char *src, const char *dst, const char *eol_str, svn_boolean_t repair, const svn_subst_keywords_t *keywords, svn_boolean_t expand, apr_pool_t *pool){ return svn_subst_copy_and_translate2(src, dst, eol_str, repair, keywords, expand, FALSE, pool);}/* Given a special file at SRC, generate a textual representation of it in a normal file at DST. Perform all allocations in POOL. */static svn_error_t *detranslate_special_file(const char *src, const char *dst, apr_pool_t *pool){ svn_stream_t *translated_stream, *dst_stream; const char *dst_tmp; apr_file_t *d; SVN_ERR(detranslated_stream_special(&translated_stream, src, pool)); /* Open a temporary destination that we will eventually atomically rename into place. */ SVN_ERR(svn_io_open_unique_file2(&d, &dst_tmp, dst, ".tmp", svn_io_file_del_none, pool)); dst_stream = svn_stream_from_aprfile(d, pool); SVN_ERR(svn_stream_copy(translated_stream, dst_stream, pool)); SVN_ERR(svn_stream_close(dst_stream)); SVN_ERR(svn_stream_close(translated_stream)); SVN_ERR(svn_io_file_close(d, pool)); /* Do the atomic rename from our temporary location. */ SVN_ERR(svn_io_file_rename(dst_tmp, dst, pool)); return SVN_NO_ERROR;}/* Given a file containing a repository representation of a special file in SRC, create the appropriate special file at location DST. Perform all allocations in POOL. */static svn_error_t *create_special_file(const char *src, const char *dst, apr_pool_t *pool){ svn_stringbuf_t *contents; char *identifier, *remainder; const char *dst_tmp, *src_tmp = NULL; svn_error_t *err; svn_node_kind_t kind; svn_boolean_t is_special; /* Check to see if we are being asked to create a special file from a special file. If so, do a temporary detranslation and work from there. */ SVN_ERR(svn_io_check_special_path(src, &kind, &is_special, pool)); if (is_special) { SVN_ERR(svn_io_open_unique_file2(NULL, &src_tmp, dst, ".tmp", svn_io_file_del_none, pool)); SVN_ERR(detranslate_special_file(src, src_tmp, pool)); src = src_tmp; } /* Read in the detranslated file. */ SVN_ERR(svn_stringbuf_from_file(&contents, src, pool)); /* If there was just a temporary detranslation, remove it now. */ if (src_tmp) SVN_ERR(svn_io_remove_file(src_tmp, pool)); /* Separate off the identifier. The first space character delimits the identifier, after which any remaining characters are specific to the actual special device being created. */ identifier = contents->data; for (remainder = identifier; *remainder; remainder++) { if (*remainder == ' ') { *remainder = '\0'; remainder++; break; } } if (! strcmp(identifier, SVN_SUBST__SPECIAL_LINK_STR)) { /* For symlinks, the type specific data is just a filesystem path that the symlink should reference. */ err = svn_io_create_unique_link(&dst_tmp, dst, remainder, ".tmp", pool); } else { /* We should return a valid error here. */ return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL, _("'%s' has unsupported special file type " "'%s'"), src, identifier); } /* If we had an error, check to see if it was because this type of special device is not supported. */ if (err) { if (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE) { svn_error_clear(err); /* Fall back to just copying the text-base. */ SVN_ERR(svn_io_open_unique_file2(NULL, &dst_tmp, dst, ".tmp", svn_io_file_del_none, pool)); SVN_ERR(svn_io_copy_file(src, dst_tmp, TRUE, pool)); } else return err; } /* Do the atomic rename from our temporary location. */ SVN_ERR(svn_io_file_rename(dst_tmp, dst, pool)); return SVN_NO_ERROR;}svn_error_t *svn_subst_copy_and_translate2(const char *src, const char *dst, const char *eol_str, svn_boolean_t repair, const svn_subst_keywords_t *keywords, svn_boolean_t expand, svn_boolean_t special, apr_pool_t *pool){ apr_hash_t *kh = kwstruct_to_kwhash(keywords, pool); return svn_subst_copy_and_translate3(src, dst, eol_str, repair, kh, expand, special, pool);}svn_error_t *svn_subst_copy_and_translate3(const char *src, const char *dst, const char *eol_str, svn_boolean_t repair, apr_hash_t *keywords, svn_boolean_t expand, svn_boolean_t special, apr_pool_t *pool){ const char *dst_tmp = NULL; svn_stream_t *src_stream, *dst_stream; apr_file_t *s = NULL, *d = NULL; /* init to null important for APR */ svn_error_t *err; svn_node_kind_t kind; svn_boolean_t path_special; SVN_ERR(svn_io_check_special_path(src, &kind, &path_special, pool)); /* If this is a 'special' file, we may need to create it or detranslate it. */ if (special || path_special) { if (expand) SVN_ERR(create_special_file(src, dst, pool)); else SVN_ERR(detranslate_special_file(src, dst, pool)); return SVN_NO_ERROR; } /* The easy way out: no translation needed, just copy. */ if (! (eol_str || (keywords && (apr_hash_count(keywords) > 0)))) return svn_io_copy_file(src, dst, FALSE, pool); /* Open source file. */ SVN_ERR(svn_io_file_open(&s, src, APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool)); /* For atomicity, we translate to a tmp file and then rename the tmp file over the real destination. */ SVN_ERR(svn_io_open_unique_file2(&d, &dst_tmp, dst, ".tmp", svn_io_file_del_on_pool_cleanup, pool)); /* Now convert our two open files into streams. */ src_stream = svn_stream_from_aprfile(s, pool); dst_stream = svn_stream_from_aprfile(d, pool); /* Translate src stream into dst stream. */ err = svn_subst_translate_stream3(src_stream, dst_stream, eol_str, repair, keywords, expand, pool); if (err) { if (err->apr_err == SVN_ERR_IO_INCONSISTENT_EOL) return svn_error_createf (SVN_ERR_IO_INCONSISTENT_EOL, err, _("File '%s' has inconsistent newlines"), svn_path_local_style(src, pool)); else return err; } /* clean up nicely. */ SVN_ERR(svn_stream_close(src_stream)); SVN_ERR(svn_stream_close(dst_stream)); SVN_ERR(svn_io_file_close(s, pool)); SVN_ERR(svn_io_file_close(d, pool)); /* Now that dst_tmp contains the translated data, do the atomic rename. */ SVN_ERR(svn_io_file_rename(dst_tmp, dst, pool)); return SVN_NO_ERROR;}svn_error_t *svn_subst_translate_string(svn_string_t **new_value, const svn_string_t *value, const char *encoding, apr_pool_t *pool){ const char *val_utf8; const char *val_utf8_lf; if (value == NULL) { *new_value = NULL; return SVN_NO_ERROR; } if (encoding) { SVN_ERR(svn_utf_cstring_to_utf8_ex2(&val_utf8, value->data, encoding, pool)); } else { SVN_ERR(svn_utf_cstring_to_utf8(&val_utf8, value->data, pool)); } SVN_ERR(svn_subst_translate_cstring2(val_utf8, &val_utf8_lf, "\n", /* translate to LF */ FALSE, /* no repair */ NULL, /* no keywords */ FALSE, /* no expansion */ pool)); *new_value = svn_string_create(val_utf8_lf, pool); return SVN_NO_ERROR;}svn_error_t *svn_subst_detranslate_string(svn_string_t **new_value, const svn_string_t *value, svn_boolean_t for_output, apr_pool_t *pool){ svn_error_t *err; const char *val_neol; const char *val_nlocale_neol; if (value == NULL) { *new_value = NULL; return SVN_NO_ERROR; } SVN_ERR(svn_subst_translate_cstring2(value->data, &val_neol, APR_EOL_STR, /* 'native' eol */ FALSE, /* no repair */ NULL, /* no keywords */ FALSE, /* no expansion */ pool)); if (for_output) { err = svn_cmdline_cstring_from_utf8(&val_nlocale_neol, val_neol, pool); if (err && (APR_STATUS_IS_EINVAL(err->apr_err))) { val_nlocale_neol = svn_cmdline_cstring_from_utf8_fuzzy(val_neol, pool); svn_error_clear(err); } else if (err) return err; } else { err = svn_utf_cstring_from_utf8(&val_nlocale_neol, val_neol, pool); if (err && (APR_STATUS_IS_EINVAL(err->apr_err))) { val_nlocale_neol = svn_utf_cstring_from_utf8_fuzzy(val_neol, pool); svn_error_clear(err); } else if (err) return err; } *new_value = svn_string_create(val_nlocale_neol, pool); return SVN_NO_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -