Checkout Tools
  • last updated 2 hours ago
Constraints
Constraints: committers
 
Constraints: files
Constraints: dates
* subversion/tests/libsvn_diff/parse-diff-test.c

(test_parse_git_tree_and_text_diff, test_parse_git_diff): Assert on

{old,new}_{executable,symlink}_bit equality with expected value instead of

the reslut of the assignment of the expected value.

Found by: Coverity <https://scan.coverity.com/>

(CID: 1356909-1356916, 1356946-1356952)

In the diff parser: parse the symlink status from the mode flags.

* subversion/include/svn_diff.h

(svn_patch_t): Rename executable bits to _bits and add

symlink bit variables.

* subversion/libsvn_client/patch.c

(contradictory_executability): Update caller.

(init_patch_target): Don't call contradictory_executability when no

executable change is described in the mode change. Update caller.

(apply_one_patch): Update caller.

* subversion/libsvn_diff/parse-diff.c

(parse_bits_into_executability): Rename to...

(parse_git_mode_bits): ... this and also parse symlink info.

(git_old_mode,

git_new_mode,

git_new_file,

git_deleted_file): Update caller.

(svn_diff_parse_next_patch): Update initialization. Reverse new bits

when using a reverse diff.

* subversion/tests/libsvn_diff/parse-diff-test.c

(test_parse_git_diff,

test_parse_git_tree_and_text_diff): Update caller. Add assertions.

  1. … 3 more files in changeset.
patch: Parse 'old mode' / 'new mode' line from git diffs and translate them

to svn:executable propchanges.

This merges the 'patch-exec' branch into trunk.

---

The following are the major changes. See the branch for detailed changes.

* subversion/include/svn_diff.h

(svn_patch_t.old_executable_p, svn_patch_t.new_executable_p): New members.

* subversion/libsvn_client/patch.c

(contradictory_executability): New function.

(init_patch_target, apply_one_patch):

Translate mode changes to svn:executable changes.

* subversion/include/private/svn_diff_private.h

(svn_diff_hunk__create_adds_single_line,

svn_diff_hunk__create_deletes_single_line): New functions.

* subversion/libsvn_diff/parse-diff.c

(add_or_delete_single_line,

svn_diff_hunk__create_adds_single_line,

svn_diff_hunk__create_deletes_single_line): New functions.

(parse_state::state_old_mode_seen,

parse_state::state_git_mode_seen): New enumerators.

(parse_bits_into_executability, git_old_mode, git_new_mode): New functions.

(git_deleted_file, git_new_file): Parse file mode.

(transitions): Parse "old mode" and "new mode" lines.

* subversion/tests/cmdline/patch_tests.py,

* subversion/tests/libsvn_diff/parse-diff-test.c:

Add unit tests.

  1. … 7 more files in changeset.
Following up on r1705038, r1705080, update expected result in the diff parse c

tests on missing EOLs.

A missing eol in the patch file shouldn't affect the actual hunk. Only a no

finale EOL marker should really create a no-final EOL result.

* subversion/tests/libsvn_diff/parse-diff-test.c

(stream_readline_diff): New function.

(check_content): Use stream_readline_diff.

Use SVN_TEST_STRING_ASSERT() in a few more C tests to improve error

reporting.

* subversion/tests/libsvn_diff/parse-diff-test.c

(test_parse_property_diff): Use SVN_TEST_STRING_ASSERT.

* subversion/tests/libsvn_subr/auth-test.c

(cleanup_callback,

test_auth_clear): Use SVN_TEST_STRING_ASSERT.

* subversion/tests/libsvn_wc/conflict-data-test.c

(test_parse_property_diff): Use SVN_TEST_STRING_ASSERT.

  1. … 2 more files in changeset.
Add a regression test for diff parsing with svn:mergeinfo.

* subversion/tests/libsvn_diff/parse-diff-test.c

(unidiff_with_mergeinfo): New test diff.

(test_parse_unidiff_with_mergeinfo, test_funcs): New test.

follow-up to r1592014:

Unbreak parse-diff-test 4 "test badly formatted git diff header"

* subversion/tests/libsvn_diff/parse-diff-test.c

(bad_git_diff_header): Remove 'copy from' and 'copy to' header lines

which are used as a fallback if a filename cannot be found in the

git --diff line. Now the test's assumptions are correct again.

Make the C tests work with the --enable-optimize configure option.

Because the main() function used to be defined in libsvn_test,

the -flto option (which performs rather aggressive link-time

optimizations) would cause the linker to remove all "unreferenced"

static functions ... which includes all the actual tests.

Which this change, main() is now defined in each test driver.

* subversion/tests/svn_test.h

(test_funcs, svn_test_max_threads): Remove external declarations.

(svn_test_main): New prototype for the (existing-but-renamed) test driver.

(SVN_TEST_MAIN): Bolierplate macro that generates a main() implementation.

* subversion/tests/svn_test_main.c

(svn_test_main): Renamed from 'main', and takes two extra parameters,

'max_threads' and 'test_funcs'. Propagates test_funcs to get_array_size,

do_test_num and do_tests_concurrently.

(get_array_size, do_test_num,

test_params_t, test_thread, do_tests_concurrently): Require a test_funcs

parameter. All uses updated.

* subversion/tests/libsvn_client/client-test.c,

subversion/tests/libsvn_client/mtcc-test.c,

subversion/tests/libsvn_delta/random-test.c,

subversion/tests/libsvn_delta/window-test.c,

subversion/tests/libsvn_diff/diff-diff3-test.c,

subversion/tests/libsvn_diff/parse-diff-test.c,

subversion/tests/libsvn_fs/fs-test.c,

subversion/tests/libsvn_fs/locks-test.c,

subversion/tests/libsvn_fs_base/

subversion/tests/libsvn_fs_base/changes-test.c,

subversion/tests/libsvn_fs_base/fs-base-test.c,

subversion/tests/libsvn_fs_base/strings-reps-test.c,

subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c,

subversion/tests/libsvn_fs_x/fs-x-pack-test.c,

subversion/tests/libsvn_fs_x/string-table-test.c,

subversion/tests/libsvn_ra/ra-test.c,

subversion/tests/libsvn_ra_local/ra-local-test.c,

subversion/tests/libsvn_repos/repos-test.c,

subversion/tests/libsvn_subr/auth-test.c,

subversion/tests/libsvn_subr/cache-test.c,

subversion/tests/libsvn_subr/checksum-test.c,

subversion/tests/libsvn_subr/compat-test.c,

subversion/tests/libsvn_subr/config-test.c,

subversion/tests/libsvn_subr/crypto-test.c,

subversion/tests/libsvn_subr/dirent_uri-test.c,

subversion/tests/libsvn_subr/error-code-test.c,

subversion/tests/libsvn_subr/error-test.c,

subversion/tests/libsvn_subr/hashdump-test.c,

subversion/tests/libsvn_subr/io-test.c,

subversion/tests/libsvn_subr/mergeinfo-test.c,

subversion/tests/libsvn_subr/named_atomic-test.c,

subversion/tests/libsvn_subr/opt-test.c,

subversion/tests/libsvn_subr/packed-data-test.c,

subversion/tests/libsvn_subr/path-test.c,

subversion/tests/libsvn_subr/prefix-string-test.c,

subversion/tests/libsvn_subr/priority-queue-test.c,

subversion/tests/libsvn_subr/revision-test.c,

subversion/tests/libsvn_subr/root-pools-test.c,

subversion/tests/libsvn_subr/skel-test.c,

subversion/tests/libsvn_subr/spillbuf-test.c,

subversion/tests/libsvn_subr/sqlite-test.c,

subversion/tests/libsvn_subr/stream-test.c,

subversion/tests/libsvn_subr/string-test.c,

subversion/tests/libsvn_subr/subst_translate-test.c,

subversion/tests/libsvn_subr/time-test.c,

subversion/tests/libsvn_subr/translate-test.c,

subversion/tests/libsvn_subr/utf-test.c,

subversion/tests/libsvn_wc/conflict-data-test.c,

subversion/tests/libsvn_wc/db-test.c,

subversion/tests/libsvn_wc/entries-compat.c,

subversion/tests/libsvn_wc/op-depth-test.c,

subversion/tests/libsvn_wc/pristine-store-test.c,

subversion/tests/libsvn_wc/wc-queries-test.c,

subversion/tests/libsvn_wc/wc-test.c:

(max_threads): Renamed from svn_test_max_threads and made static.

(test_funcs): Made static.

(SVN_TEST_MAIN): Expanded boilerplate main() function.

  1. … 54 more files in changeset.
Add "--parallel" option to our C tests.

Besides shaving off a few seconds off our total test execution time,

parallel execution also stresses our code and the tests themselves

harder. It uncovers things like improperly separated working sets

that make post-failure analysis harder.

Parallel mode is only available with APR 1.3+ and threads enabled.

The option will simply be ignored in other configurations. Further

limitations are cleanups being delayed to after all tests completed

and segfaults not being intercepted.

Some tests can't be executed in parallel. Therefore, we introduce

svn_test_max_threads a simple upper limit to the number of threads

supported that each test must define alongside the test_funcs array.

This patch sets it to "1" in many cases because the tests are so

small that multi-threaded execution is simply not worth it.

* build/run_tests.py

(TestHarness._run_c_test): Pass --parallel option to the individual

test applications.

* subversion/tests/svn_test.h

(svn_test_max_threads): Declare new external setting to be set by

every test application.

* subversion/tests/svn_test_main.c

(parallel): New command line option presence flag.

(parallel_opt,

cl_options): Declare the new "--parallel" option.

(svn_test_add_dir_cleanup): Synchronize shared pool access since

this might be called from multiple

threads at the same time.

(log_results): Result logger function factored out from do_test_num

to be shared between serialized and parallel test

execution code.

(do_test_num): Use that new function.

(test_params_t,

test_thread,

do_tests_concurrently): Threads, their parameter and the thread

starter for thread-pooled test execution.

(main): Handle the new option.

Call concurrent execution when in PARALLEL mode.

* subversion/tests/libsvn_delta/random-test.c

subversion/tests/libsvn_subr/named_atomic-test.c

(svn_test_max_threads): These tests don't support concurrent execution.

* subversion/tests/libsvn_delta/random-test.c

subversion/tests/libsvn_delta/window-test.c

subversion/tests/libsvn_diff/parse-diff-test.c

subversion/tests/libsvn_ra_local/ra-local-test.c

subversion/tests/libsvn_ra/ra-test.c

subversion/tests/libsvn_subr/auth-test.c

subversion/tests/libsvn_subr/cache-test.c

subversion/tests/libsvn_subr/checksum-test.c

subversion/tests/libsvn_subr/compat-test.c

subversion/tests/libsvn_subr/config-test.c

subversion/tests/libsvn_subr/crypto-test.c

subversion/tests/libsvn_subr/dirent_uri-test.c

subversion/tests/libsvn_subr/error-code-test.c

subversion/tests/libsvn_subr/error-test.c

subversion/tests/libsvn_subr/hashdump-test.c

subversion/tests/libsvn_subr/mergeinfo-test.c

subversion/tests/libsvn_subr/named_atomic-test.c

subversion/tests/libsvn_subr/opt-test.c

subversion/tests/libsvn_subr/packed-data-test.c

subversion/tests/libsvn_subr/path-test.c

subversion/tests/libsvn_subr/prefix-string-test.c

subversion/tests/libsvn_subr/priority-queue-test.c

subversion/tests/libsvn_subr/revision-test.c

subversion/tests/libsvn_subr/root-pools-test.c

subversion/tests/libsvn_subr/skel-test.c

subversion/tests/libsvn_subr/spillbuf-test.c

subversion/tests/libsvn_subr/sqlite-test.c

subversion/tests/libsvn_subr/stream-test.c

subversion/tests/libsvn_subr/string-test.c

subversion/tests/libsvn_subr/subst_translate-test.c

subversion/tests/libsvn_subr/time-test.c

subversion/tests/libsvn_subr/utf-test.c

subversion/tests/libsvn_wc/conflict-data-test.c

subversion/tests/libsvn_wc/wc-queries-test.c:

(svn_test_max_threads): These are too small to benefit from multi-threading.

* subversion/tests/libsvn_client/client-test.c

subversion/tests/libsvn_diff/diff-diff3-test.c

subversion/tests/libsvn_fs_base/changes-test.c

subversion/tests/libsvn_fs_base/fs-base-test.c

subversion/tests/libsvn_fs_base/strings-reps-test.c

subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c

subversion/tests/libsvn_fs/fs-test.c

subversion/tests/libsvn_fs/locks-test.c

subversion/tests/libsvn_fs_x/fs-x-pack-test.c

subversion/tests/libsvn_fs_x/string-table-test.c

subversion/tests/libsvn_repos/repos-test.c

subversion/tests/libsvn_subr/io-test.c

subversion/tests/libsvn_subr/translate-test.c

subversion/tests/libsvn_wc/db-test.c

subversion/tests/libsvn_wc/op-depth-test.c

subversion/tests/libsvn_wc/wc-test.c

(svn_test_max_threads): Set concurrency limit to whatever various test

runs suggested as the most efficient value.

* subversion/tests/libsvn_wc/entries-compat.c

subversion/tests/libsvn_wc/pristine-store-test.c

(svn_test_max_threads): Set concurrency limit to "unbounded".

  1. … 54 more files in changeset.
* subversion/tests/libsvn_diff/parse-diff-test.c

(test_parse_unidiff_lacking_trailing_eol): Remove obsolete comment.

Found by: danielsh

Follow-up to r1206724: Fix an issue #3991 diff parsing test to make it pass.

Found by: danielsh

* subversion/tests/libsvn_diff/parse-diff-test.c

(check_content): Allow non-empty lines when EOF is hit before EOL.

(test_parse_unidiff_lacking_trailing_eol): Update test expectations,

the hunk text has no trailing EOL.

(test_funcs): Remove XFAIL from test_parse_unidiff_lacking_trailing_eol.

Add a C test for issue #3991.

* subversion/tests/libsvn_diff/parse-diff-test.c

(unidiff_lacking_trailing_eol): New global string.

(test_parse_unidiff_lacking_trailing_eol): New test.

(test_funcs): Run it, XFail.

Make the parse-diff tests close file handles before passing the name to the

subversion api to avoid triggering problems when testing for open file

handles and locks.

Do this by switching to generated tempfiles using the normal temp api.

(The apr api doesn't support delete at pool cleanup)

* subversion/tests/libsvn_diff/parse-diff-test.c

(create_patch_file): Remove fname argument and switch to subversion api.

(test_parse_unidiff,

test_parse_git_diff,

test_parse_git_tree_and_text_diff,

test_bad_git_diff_headers,

test_parse_property_diff,

test_parse_property_and_text_diff,

test_parse_diff_symbols_in_prop_unidiff,

test_git_diffs_with_spaces_diff): Update callers.

Fix issue #3809 - 'svn patch' accepts invalid git diff headers.

* subversion/libsvn_diff/parse-diff.c

(svn_diff_parse_next_patch): Disallow non-header lines in the header.

* subversion/tests/libsvn_diff/parse-diff-test.c

(bad_git_diff_header): Remove sentence that says that the test is

failing.

(test_funcs): Remove XFAIL marker.

  1. … 1 more file in changeset.
Associate another XFailing test with appropriate issue.

* notes/xfail-status: Update

* subversion/tests/libsvn_diff/parse-diff-test.c

(bad_git_diff_header): Add a comment about why this test is failing and

its associated issue #3809.

  1. … 1 more file in changeset.
Fix issue #3764, "svn patch opens the patch file too many times".

Make the diff parser use only a single file handle per patch file.

Before this change, the parser opened several file handles for each hunk

in the patch file. Since file descriptors are a limited resource this

imposed a hard upper bound on the number of hunks svn patch could process.

Instead of using streams mapped onto APR file ranges to read hunks,

track offsets hunks have within the patch file and perform seeks within

the patch file directly.

Some API changes were required but these APIs are all new in 1.7.

Also do some cosmetic house-keeping.

* subversion/include/svn_diff.h

(svn_diff_hunk_readline_diff_text, svn_diff_hunk_readline_original_text.

svn_diff_hunk_readline_modified_text. svn_diff_hunk_reset_diff_text,

svn_diff_hunk_reset_original_text, svn_diff_hunk_reset_modified_text,

svn_diff_parse_next_patch): Adjust declarations.

(svn_prop_patch_t): Advise API users not to allocate this structure directly.

(svn_patch_t): As previous, and remove unused 'path' and 'patch_file' fields.

(svn_diff_close_patch): Remove declaration.

(svn_patch_file_t, svn_diff_open_patch_file,

svn_diff_close_patch_file): Declare.

* subversion/libsvn_diff/parse-diff.c

(): Include svn_dep_compat.h for APR_SIZE_MAX.

(svn_diff__hunk_range): New file-local type. Describes a hunk's range in

the patch file, in byte offsets, including a "current" position within

this range.

(svn_diff_hunk_t): Remove the diff_text, original_text and modified_text

svn_stream_t members. Instead, add an apr_file and ranges for the hunk

texts called diff_text_range, original_text_range, and modified_text_range,

respectively.

(svn_diff_hunk_reset_diff_text, svn_diff_hunk_reset_original_text,

svn_diff_hunk_reset_modified_text, scan_eol, hunk_readline,

svn_diff_hunk_readline_original_text, svn_diff_hunk_readline_modified_text,

svn_diff_hunk_readline_diff_text, parse_next_hunk): Re-implement, mostly

to switch from using streams to using plain APR files and hunk ranges.

(readline, hunk_readline_original_or_modified): New helpers, descendents

of the old stream-based hunk_readline() function.

(close_hunk): Remove.

(svn_patch_file_t): New type. Opaque to users of libsvn_diff.

(svn_diff_open_patch_file): New function to open a patch file.

(svn_diff_parse_next_patch): Expect svn_patch_file_t instead of an APR file

and adjust accordingly. Some cosmetic tweaks while here.

(svn_diff_close_patch): Remove.

(svn_diff_close_patch_file): New function to close a patch file.

* subversion/libsvn_client/patch.c

(match_hunk, match_existing_target, apply_hunk, apply_patches): Adjust to

diff parser API changes.

* subversion/tests/libsvn_diff/parse-diff-test.c

(create_patch_file, check_content, test_parse_unidiff, test_parse_git_diff,

test_parse_git_tree_and_text_diff, test_bad_git_diff_headers,

test_parse_property_diff, test_parse_property_and_text_diff,

test_parse_diff_symbols_in_prop_unidiff,

test_git_diffs_with_spaces_diff): Adjust to diff parser API changes.

  1. … 3 more files in changeset.
Just padding my stats.

(Actually, doing my regular trailing whitespace removal, similar to r875968.)

* everywhere:

for extsn in c h cpp java py pl rb; do

sed -i -e 's/[ \t]*$//' `find . -name "*.$extsn" | xargs grep '[ \t]$' -l`

done

  1. … 166 more files in changeset.
Refactor the C-unit tests for parsing diffs.

* subversion/tests/libsvn_diff/parse-diff-test.c

(...): Use SVN_TEST_STRING_ASSERT() when comparing strings instead

of SVN_TEST_ASSERT(! strcmp(...). This change makes the code more

readable and gives a better error message.

Revert r996581 and r996596, which broke the use case where svn patch

is used to apply a patch which was accidentally produced in reverse.

Rather than hard-wiring the way svn patch selects target filenames

from paths provided in the diff, we'll need to make the behaviour

configurable.

See for related discussion the following post (and follow-ups):

Date: Tue, 14 Sep 2010 12:49:06 +0100

From: Julian Foad

To: Stefan Sperling

Cc: dev@

Subject: Re: svn commit: r996581 - in /subversion/trunk/subversion:

libsvn_diff/parse-diff.c tests/cmdline/patch_tests.py

Message-ID: <1284464946.2305.1952.camel@edith>

http://svn.haxx.se/dev/archive-2010-09/0262.shtml

  1. … 2 more files in changeset.
[ Note from the future: Reverted in r997065 ]

Followup to r996581.

* subversion/tests/libsvn_diff/parse-diff-test.c

(test_parse_unidiff): Don't swap filenames for reverse diff.

Fix the diff parser to look for the correct first line of a git diff.

The change that is beeing applied is s/git --diff/diff --git/.

* subversion/libsvn_diff/parse-diff.c

(parse_next_hunk,

git_start,

svn_diff_parse_next_patch): Check for 'diff --git' as first line of a

git diff header.

* subversion/libsvn_diff/parse-diff-test.c

(git_unidiff,

git_tree_and_text_unidiff,

bad_git_diff_header,

path_with_spaces_unidiff): Use 'diff --git as first line of git

diff headers.

Found by: stsp

  1. … 1 more file in changeset.
Rename 'svn_hunk_t' to 'svn_diff_hunk_t', in order to keep a common

'svn_diff_' prefix on diff library symbols.

* subversion/include/svn_diff.h,

subversion/libsvn_diff/parse-diff.c

(svn_hunk_t): Rename to 'svn_diff_hunk_t'. Update all references.

* subversion/libsvn_client/patch.c,

subversion/tests/libsvn_diff/parse-diff-test.c,

subversion/bindings/swig/svn_diff.i

Update all references.

  1. … 4 more files in changeset.
Make the diff parser able to properly handle added and deleted files with

content. Previously, only empty files worked.

Just as for copies and renames we may or may not have '---' and '+++'

lines following the header lines involving tree changes. Handle the

add and delete case in the same way as the copy and move ones.

* subversion/libsvn_diff/parse-diff.c

(git_minus,

git_plus): Store '/dev/null' as filename if given.

(git_new_file,

git_deleted_file): Return a state saying we have seen header lines

that involves tree changes to the target.

(svn_diff_parse_next_patch): Add cases where the input is '/dev/null'

to the lookup-table.

* subversion/tests/libsvn_diff/parse-diff-test.c

(git_tree_and_text_unidiff): Fix typo.

(test_funcs): Remove XFail marker for

test_parse_git_tree_and_text_diff().

  1. … 1 more file in changeset.
Adjust a C-unit test for parsing git diffs to include added and deleted

paths.

Currently the parser does not handle paths without a leading "a/" or "b/", i.e.

"/dev/null" that is used for added and deleted paths does not work.

* subversion/libsvn_diff/parse-diff-test.c

(git_tree_and_text_unidiff): Add an added and a deleted file to the patch

data.

(test_parse_git_tree_and_text_diff): Add checks for the new files.

(test_funcs): Mark test_parse_git_tree_and_text_diff() as XFailing.

* subversion/tests/libsvn_diff/parse-diff-tests.c

(git_tree_and_text_unidiff): Add '---' and '+++' lines to the input

patch. For patches with text changes, we should always have those

headers.

* subversion/tests/libsvn_diff/parse-diff-tests.c

(test_git_diffs_with_spaces_diff): Follow-up to r982582. Remove a

dangling debug statement.

Found by: pburba

Adjust a C-unit test for parsing git diffs to have " b/" as part of

the paths.

The diff-parser searches for " b/" to find the start of old_path.

* subversion/tests/libsvn_diff/parse-diff-tests.c

(git_diff_with_spaces_diff,

test_git_diffs_with_spaces_diff): See above.

Make the diff parser able to handle paths with spaces in the

"--git diff a/path b/path" line. At the same time start

recording path information from other header fields.

We only need the filenames from the --git diff line if we're

dealing with added or deleted empty files. In those cases, the

paths should be identical.

The git_start() function probably needs some adjusting but it passes

the tests so I'm committing it. :).

* subversion/libsvn_diff/parse-diff.c

(git_start): First check that we have a header line on the form

"--git diff a/.+ b/.+". Then grab the old and new filename if

they are the same.

(git_minus,

git_plus,

git_move_from,

git_move_to,

git_copy_from,

git_copy_to): Start grabbing filenames.

* subversion/tests/libsvn_diff/parse-diff-test.c

(test_funcs): Remove XFail marker for test_git_diffs_with_spaces_diff.

  1. … 1 more file in changeset.
Adjust the parser to match aginst lines beginning with 'rename {from/to}' instead of

'moved {from,to}'. Using 'moved' was plain wrong and was a mistake caused by

sloppiness.

* subversion/libsvn_diff/parse-diff.c

(svn_diff_parse_next_patch): Adjust the parser.

* subversion/tests/libsvn_diff/parse-diff-test.c

(git_tree_and_text_unidiff): Adjust test data.

  1. … 1 more file in changeset.
Add XFailing test for parsing git diffs with spaces in the paths.

Note that we only need to parse the '--git diff a/path b/path' line

for added and deleted empty files. In all other cases we have other

header lines to obtain the information from.

* subversion/tests/libsvn_diff/parse-diff-test.c

(path_with_spaces_unidiff): New unidiff test data.

(test_git_diffs_with_spaces_diff): New.

(test_funcs): Add test_git_diffs_with_spaces_diff() as XFailing.