Git 2.24-rc1

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE4fA2sf7nIh/HeOzvsLXohpav5ssFAl2xOfYACgkQsLXohpav
 5ss0lg//bIacUJToa4dfT7FHw/uG4x0hlwOEJ8Iul9TifIPCQsRM2lOQkCgde+Dd
 6nXu4HLIjCBpFcUmrfEPErOp8eqEshY4DJ6n7UadAxm+uUB7PWI4r7v24JJtFtyM
 VrrqlkhgiMo72h+KxTKNZeiY+s/aD7yGwU//2cGckTgr0H0qxt2+NrOeH3jYMQ1p
 NiSZK3xDKUUxIf3XmKn6GjAS5fXnBsfY2gIj7xg4mhyQDc3Ui+vHN6cr5qESYqa+
 O1CmZEzBxksxN0kDgF53bqry9zmRr1Z8Hfocqc9xVu43tObohS/PZ8T9bnTH97UJ
 tDBfRankgXbjoLyUmct+eYlm/23m8h0fKPxNT1XXoLsRxiouJgIg+iIj86QbsAm6
 rF1XYubiTUtKiMcmYMHK1vlXRPTUvkuJp/JhQyui5vdSE/Q7+uSp/4fLpdvgpE1H
 3NqFtYA+rkxR/cT8+ldL8iDw5Y5J4O6egwfzEB8ZYAsMLwFc7s/aM312srSt9EN+
 9j80WeUju3nuAQlhqhYMVERHm84WewcPD8AaBepFNfhJLmtVVCOovQEsc62gRnwW
 B27EXjKr+ASrMa7rg73RWiqC13gAh4c9kS8FUVZVHstRnGlO5dmiHTU6td+Id10r
 IV4i7pyFQA0/1IXd8O0J6F9iUvPTIOSqzVhywZIkDkRcXNQqOdg=
 =zfW8
 -----END PGP SIGNATURE-----

Merge tag 'v2.24.0-rc1' of github.com:git/git into master

Git 2.24-rc1

* tag 'v2.24.0-rc1' of github.com:git/git:
  Git 2.24-rc1
  repo-settings: read an int for index.version
  ci: fix GCC install in the Travis CI GCC OSX job
  Eleventh batch
  ci(osx): use new location of the `perforce` cask
  t7419: change test_must_fail to ! for grep
  t4014: make output-directory tests self-contained
  ci(visual-studio): actually run the tests in parallel
  ci(visual-studio): use strict compile flags, and optimization
  userdiff: fix some corner cases in dts regex
  test-progress: fix test failures on big-endian systems
  completion: clarify installation instruction for zsh
  grep: avoid leak of chartables in PCRE2
  grep: make PCRE2 aware of custom allocator
  grep: make PCRE1 aware of custom allocator
  remote-curl: pass on atomic capability to remote side
  diff-highlight: fix a whitespace nit
  fsmonitor: don't fill bitmap with entries to be removed
This commit is contained in:
Jiang Xin 2019-10-28 13:18:55 +08:00
commit 468d356a81
27 changed files with 247 additions and 29 deletions

View file

@ -75,6 +75,9 @@ UI, Workflows & Features
submodules, but this did not apply to "git fetch --multiple" that
fetches from multiple remote repositories. It now does.
* The installation instruction for zsh completion script (in
contrib/) has been a bit improved.
Performance, Internal Implementation, Development Support etc.
@ -337,6 +340,10 @@ Fixes since v2.23
corrected.
(merge 556895d0c8 jj/stash-reset-only-toplevel later to maint).
* The atomic push over smart HTTP transport did not work, which has
been corrected.
(merge 6f1194246a bc/smart-http-atomic-push later to maint).
* Other code cleanup, docfix, build fix, etc.
(merge d1387d3895 en/fast-import-merge-doc later to maint).
(merge 1c24a54ea4 bm/repository-layout-typofix later to maint).
@ -385,3 +392,6 @@ Fixes since v2.23
(merge 5cc6a4be11 rs/http-push-simplify later to maint).
(merge a81e42d235 rs/column-use-utf8-strnwidth later to maint).
(merge 062a309d36 rs/remote-curl-use-argv-array later to maint).
(merge 3b3c79f6c9 nr/diff-highlight-indent-fix later to maint).
(merge 3444ec2eb2 wb/fsmonitor-bitmap-fix later to maint).
(merge 10da030ab7 cb/pcre2-chartables-leakfix later to maint).

View file

@ -509,6 +509,11 @@ set by Git if the remote helper has the 'option' capability.
Indicate that only the objects wanted need to be fetched, not
their dependents.
'option atomic' {'true'|'false'}::
When pushing, request the remote server to update refs in a single atomic
transaction. If successful, all refs will be updated, or none will. If the
remote side does not support this capability, the push will fail.
SEE ALSO
--------
linkgit:git-remote[1]

View file

@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
DEF_VER=v2.24.0-rc0
DEF_VER=v2.24.0-rc1
LF='
'

View file

@ -157,7 +157,7 @@ jobs:
displayName: 'Download git-sdk-64-minimal'
- powershell: |
& git-sdk-64-minimal\usr\bin\bash.exe -lc @"
make vcxproj
make NDEBUG=1 DEVELOPER=1 vcxproj
"@
if (!$?) { exit(1) }
displayName: Generate Visual Studio Solution
@ -255,7 +255,7 @@ jobs:
cd t &&
PATH=\"`$PWD/helper:`$PATH\" &&
test-tool.exe run-command testsuite -V -x --write-junit-xml \
test-tool.exe run-command testsuite --jobs=10 -V -x --write-junit-xml \
`$(test-tool.exe path-utils slice-tests \
`$SYSTEM_JOBPOSITIONINPHASE `$SYSTEM_TOTALJOBSINPHASE t[0-9]*.sh)
"@

View file

@ -1147,5 +1147,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
run_pager(&opt, prefix);
clear_pathspec(&pathspec);
free_grep_patterns(&opt);
grep_destroy();
return !hit;
}

View file

@ -40,9 +40,15 @@ osx-clang|osx-gcc)
test -z "$BREW_INSTALL_PACKAGES" ||
brew install $BREW_INSTALL_PACKAGES
brew link --force gettext
brew cask install perforce || {
# Update the definitions and try again
git -C "$(brew --repository)"/Library/Taps/homebrew/homebrew-cask pull &&
brew cask install perforce
} ||
brew install caskroom/cask/perforce
case "$jobname" in
osx-gcc)
brew link gcc ||
brew link gcc@8
;;
esac

View file

@ -11,8 +11,9 @@
#
# zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh
#
# The recommended way to install this script is to copy to '~/.zsh/_git', and
# then add the following to your ~/.zshrc file:
# The recommended way to install this script is to make a copy of it in
# ~/.zsh/ directory as ~/.zsh/git-completion.zsh and then add the following
# to your ~/.zshrc file:
#
# fpath=(~/.zsh $fpath)

View file

@ -72,7 +72,7 @@ sub handle_line {
(?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|"
[ ]* # trailing whitespace for merges
/x) {
my $graph_prefix = $&;
my $graph_prefix = $&;
# We must flush before setting graph indent, since the
# new commit may be indented differently from what we

View file

@ -14,8 +14,13 @@ struct trace_key trace_fsmonitor = TRACE_KEY_INIT(FSMONITOR);
static void fsmonitor_ewah_callback(size_t pos, void *is)
{
struct index_state *istate = (struct index_state *)is;
struct cache_entry *ce = istate->cache[pos];
struct cache_entry *ce;
if (pos >= istate->cache_nr)
BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" >= %u)",
(uintmax_t)pos, istate->cache_nr);
ce = istate->cache[pos];
ce->ce_flags &= ~CE_FSMONITOR_VALID;
}
@ -50,17 +55,24 @@ int read_fsmonitor_extension(struct index_state *istate, const void *data,
}
istate->fsmonitor_dirty = fsmonitor_dirty;
if (istate->fsmonitor_dirty->bit_size > istate->cache_nr)
BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)",
(uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr);
trace_printf_key(&trace_fsmonitor, "read fsmonitor extension successful");
return 0;
}
void fill_fsmonitor_bitmap(struct index_state *istate)
{
unsigned int i;
unsigned int i, skipped = 0;
istate->fsmonitor_dirty = ewah_new();
for (i = 0; i < istate->cache_nr; i++)
if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID))
ewah_set(istate->fsmonitor_dirty, i);
for (i = 0; i < istate->cache_nr; i++) {
if (istate->cache[i]->ce_flags & CE_REMOVE)
skipped++;
else if (!(istate->cache[i]->ce_flags & CE_FSMONITOR_VALID))
ewah_set(istate->fsmonitor_dirty, i - skipped);
}
}
void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
@ -71,6 +83,10 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
uint32_t ewah_size = 0;
int fixup = 0;
if (istate->fsmonitor_dirty->bit_size > istate->cache_nr)
BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)",
(uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr);
put_be32(&hdr_version, INDEX_EXTENSION_VERSION);
strbuf_add(sb, &hdr_version, sizeof(uint32_t));
@ -236,6 +252,9 @@ void tweak_fsmonitor(struct index_state *istate)
}
/* Mark all previously saved entries as dirty */
if (istate->fsmonitor_dirty->bit_size > istate->cache_nr)
BUG("fsmonitor_dirty has more entries than the index (%"PRIuMAX" > %u)",
(uintmax_t)istate->fsmonitor_dirty->bit_size, istate->cache_nr);
ewah_each_bit(istate->fsmonitor_dirty, fsmonitor_ewah_callback, istate);
/* Now mark the untracked cache for fsmonitor usage */

47
grep.c
View file

@ -16,6 +16,20 @@ static int grep_source_is_binary(struct grep_source *gs,
static struct grep_opt grep_defaults;
#ifdef USE_LIBPCRE2
static pcre2_general_context *pcre2_global_context;
static void *pcre2_malloc(PCRE2_SIZE size, MAYBE_UNUSED void *memory_data)
{
return malloc(size);
}
static void pcre2_free(void *pointer, MAYBE_UNUSED void *memory_data)
{
return free(pointer);
}
#endif
static const char *color_grep_slots[] = {
[GREP_COLOR_CONTEXT] = "context",
[GREP_COLOR_FILENAME] = "filename",
@ -150,12 +164,28 @@ int grep_config(const char *var, const char *value, void *cb)
* Initialize one instance of grep_opt and copy the
* default values from the template we read the configuration
* information in an earlier call to git_config(grep_config).
*
* If using PCRE, make sure that the library is configured
* to use the same allocator as Git (e.g. nedmalloc on Windows).
*
* Any allocated memory needs to be released in grep_destroy().
*/
void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix)
{
struct grep_opt *def = &grep_defaults;
int i;
#if defined(USE_LIBPCRE2)
if (!pcre2_global_context)
pcre2_global_context = pcre2_general_context_create(
pcre2_malloc, pcre2_free, NULL);
#endif
#ifdef USE_LIBPCRE1
pcre_malloc = malloc;
pcre_free = free;
#endif
memset(opt, 0, sizeof(*opt));
opt->repo = repo;
opt->prefix = prefix;
@ -178,6 +208,13 @@ void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix
color_set(opt->colors[i], def->colors[i]);
}
void grep_destroy(void)
{
#ifdef USE_LIBPCRE2
pcre2_general_context_free(pcre2_global_context);
#endif
}
static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt)
{
/*
@ -461,7 +498,6 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
PCRE2_UCHAR errbuf[256];
PCRE2_SIZE erroffset;
int options = PCRE2_MULTILINE;
const uint8_t *character_tables = NULL;
int jitret;
int patinforet;
size_t jitsizearg;
@ -470,11 +506,15 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
p->pcre2_compile_context = NULL;
/* pcre2_global_context is initialized in append_grep_pattern */
if (opt->ignore_case) {
if (!opt->ignore_locale && has_non_ascii(p->pattern)) {
character_tables = pcre2_maketables(NULL);
if (!pcre2_global_context)
BUG("pcre2_global_context uninitialized");
p->pcre2_tables = pcre2_maketables(pcre2_global_context);
p->pcre2_compile_context = pcre2_compile_context_create(NULL);
pcre2_set_character_tables(p->pcre2_compile_context, character_tables);
pcre2_set_character_tables(p->pcre2_compile_context,
p->pcre2_tables);
}
options |= PCRE2_CASELESS;
}
@ -571,6 +611,7 @@ static void free_pcre2_pattern(struct grep_pat *p)
pcre2_compile_context_free(p->pcre2_compile_context);
pcre2_code_free(p->pcre2_pattern);
pcre2_match_data_free(p->pcre2_match_data);
free((void *)p->pcre2_tables);
}
#else /* !USE_LIBPCRE2 */
static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt)

2
grep.h
View file

@ -78,6 +78,7 @@ struct grep_pat {
pcre2_code *pcre2_pattern;
pcre2_match_data *pcre2_match_data;
pcre2_compile_context *pcre2_compile_context;
const uint8_t *pcre2_tables;
uint32_t pcre2_jit_on;
unsigned fixed:1;
unsigned is_fixed:1;
@ -172,6 +173,7 @@ struct grep_opt {
void init_grep_defaults(struct repository *);
int grep_config(const char *var, const char *value, void *);
void grep_init(struct grep_opt *, struct repository *repo, const char *prefix);
void grep_destroy(void);
void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);

View file

@ -40,7 +40,8 @@ struct options {
push_cert : 2,
deepen_relative : 1,
from_promisor : 1,
no_dependents : 1;
no_dependents : 1,
atomic : 1;
};
static struct options options;
static struct string_list cas_options = STRING_LIST_INIT_DUP;
@ -148,6 +149,14 @@ static int set_option(const char *name, const char *value)
else
return -1;
return 0;
} else if (!strcmp(name, "atomic")) {
if (!strcmp(value, "true"))
options.atomic = 1;
else if (!strcmp(value, "false"))
options.atomic = 0;
else
return -1;
return 0;
} else if (!strcmp(name, "push-option")) {
if (*value != '"')
string_list_append(&options.push_options, value);
@ -1196,6 +1205,8 @@ static int push_git(struct discovery *heads, int nr_spec, const char **specs)
argv_array_push(&args, "--signed=yes");
else if (options.push_cert == SEND_PACK_PUSH_CERT_IF_ASKED)
argv_array_push(&args, "--signed=if-asked");
if (options.atomic)
argv_array_push(&args, "--atomic");
if (options.verbosity == 0)
argv_array_push(&args, "--quiet");
else if (options.verbosity > 1)

View file

@ -22,7 +22,7 @@ void prepare_repo_settings(struct repository *r)
UPDATE_DEFAULT_BOOL(r->settings.core_commit_graph, 1);
UPDATE_DEFAULT_BOOL(r->settings.gc_write_commit_graph, 1);
if (!repo_config_get_bool(r, "index.version", &value))
if (!repo_config_get_int(r, "index.version", &value))
r->settings.index_version = value;
if (!repo_config_get_maybe_bool(r, "core.untrackedcache", &value)) {
if (value == 0)

View file

@ -29,7 +29,7 @@ void progress_test_force_update(void);
int cmd__progress(int argc, const char **argv)
{
uint64_t total = 0;
int total = 0;
const char *title;
struct strbuf line = STRBUF_INIT;
struct progress *progress;

View file

@ -87,6 +87,10 @@ test_index_version () {
}
test_expect_success 'index version config precedence' '
test_index_version 0 false 0 2 &&
test_index_version 2 false 0 2 &&
test_index_version 3 false 0 2 &&
test_index_version 4 false 0 4 &&
test_index_version 2 false 4 4 &&
test_index_version 2 true 0 2 &&
test_index_version 0 true 0 4 &&

View file

@ -1615,17 +1615,20 @@ test_expect_success 'format-patch -o with no leading directories' '
'
test_expect_success 'format-patch -o with leading existing directories' '
git format-patch -o patches/side master..side &&
rm -rf existing-dir &&
mkdir existing-dir &&
git format-patch -o existing-dir/patches master..side &&
count=$(git rev-list --count master..side) &&
ls patches/side >list &&
ls existing-dir/patches >list &&
test_line_count = $count list
'
test_expect_success 'format-patch -o with leading non-existing directories' '
rm -fr patches &&
git format-patch -o patches/side master..side &&
rm -rf non-existing-dir &&
git format-patch -o non-existing-dir/patches master..side &&
count=$(git rev-list --count master..side) &&
ls patches/side >list &&
test_path_is_dir non-existing-dir &&
ls non-existing-dir/patches >list &&
test_line_count = $count list
'

View file

@ -0,0 +1,9 @@
/ {
label_1: node1@ff00 {
RIGHT@deadf00,4000 {
boolean-prop1;
ChangeMe;
};
};
};

View file

@ -0,0 +1,13 @@
/ {
label_1: node1@ff00 {
RIGHT@deadf00,4000 {
multilineprop = <3>,
<4>,
<5>,
<6>,
<7>;
ChangeMe = <0xffeedd00>;
};
};
};

View file

@ -1,4 +1,4 @@
/RIGHT { /* Technically just supposed to be a slash */
/ { RIGHT /* Technically just supposed to be a slash and brace */
#size-cells = <1>;
ChangeMe = <0xffeedd00>;

8
t/t4018/dts-root-comment Normal file
View file

@ -0,0 +1,8 @@
/ { RIGHT /* Technically just supposed to be a slash and brace */
#size-cells = <1>;
/* This comment should be ignored */
some-property = <40+2>;
ChangeMe = <0xffeedd00>;
};

View file

@ -184,11 +184,12 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
test_config -C "$d" http.receivepack true &&
up="$HTTPD_URL"/smart/atomic-branches.git &&
# Tell "$up" about two branches for now
# Tell "$up" about three branches for now
test_commit atomic1 &&
test_commit atomic2 &&
git branch collateral &&
git push "$up" master collateral &&
git branch other &&
git push "$up" master collateral other &&
# collateral is a valid push, but should be failed by atomic push
git checkout collateral &&
@ -226,6 +227,41 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output
'
test_expect_success 'push --atomic fails on server-side errors' '
# Use previously set up repository
d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
test_config -C "$d" http.receivepack true &&
up="$HTTPD_URL"/smart/atomic-branches.git &&
# break ref updates for other on the remote site
mkdir "$d/refs/heads/other.lock" &&
# add the new commit to other
git branch -f other collateral &&
# --atomic should cause entire push to be rejected
test_must_fail git push --atomic "$up" atomic other 2>output &&
# the new branch should not have been created upstream
test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
# upstream should still reflect atomic2, the last thing we pushed
# successfully
git rev-parse atomic2 >expected &&
# ...to other.
git -C "$d" rev-parse refs/heads/other >actual &&
test_cmp expected actual &&
# the new branch should not have been created upstream
test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&
# the failed refs should be indicated to the user
grep "^ ! .*rejected.* other -> other .*atomic transaction failed" output &&
# the collateral failure refs should be indicated to the user
grep "^ ! .*rejected.* atomic -> atomic .*atomic transaction failed" output
'
test_expect_success 'push --all can push to empty repo' '
d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git &&
git init --bare "$d" &&

View file

@ -34,7 +34,7 @@ test_expect_success 'submodule config cache setup' '
test_expect_success 'ensure submodule branch is unset' '
(cd super &&
test_must_fail grep branch .gitmodules
! grep branch .gitmodules
)
'
@ -54,7 +54,7 @@ test_expect_success 'test submodule set-branch --branch' '
test_expect_success 'test submodule set-branch --default' '
(cd super &&
git submodule set-branch --default submodule &&
test_must_fail grep branch .gitmodules &&
! grep branch .gitmodules &&
git submodule update --remote &&
cat <<-\EOF >expect &&
a
@ -80,7 +80,7 @@ test_expect_success 'test submodule set-branch -b' '
test_expect_success 'test submodule set-branch -d' '
(cd super &&
git submodule set-branch -d submodule &&
test_must_fail grep branch .gitmodules &&
! grep branch .gitmodules &&
git submodule update --remote &&
cat <<-\EOF >expect &&
a

View file

@ -354,4 +354,21 @@ test_expect_success 'discard_index() also discards fsmonitor info' '
test_cmp expect actual
'
# Test staging/unstaging files that appear at the end of the index. Test
# file names begin with 'z' so that they are sorted to the end of the index.
test_expect_success 'status succeeds after staging/unstaging ' '
test_create_repo fsmonitor-stage-unstage &&
(
cd fsmonitor-stage-unstage &&
test_commit initial &&
git update-index --fsmonitor &&
removed=$(test_seq 1 100 | sed "s/^/z/") &&
touch $removed &&
git add $removed &&
git config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-env" &&
FSMONITOR_LIST="$removed" git restore -S $removed &&
FSMONITOR_LIST="$removed" git status
)
'
test_done

24
t/t7519/fsmonitor-env Executable file
View file

@ -0,0 +1,24 @@
#!/bin/sh
#
# An test hook script to integrate with git to test fsmonitor.
#
# The hook is passed a version (currently 1) and a time in nanoseconds
# formatted as a string and outputs to stdout all files that have been
# modified since the given time. Paths must be relative to the root of
# the working tree and separated by a single NUL.
#
#echo "$0 $*" >&2
if test "$#" -ne 2
then
echo "$0: exactly 2 arguments expected" >&2
exit 2
fi
if test "$1" != 1
then
echo "Unsupported core.fsmonitor hook version." >&2
exit 1
fi
printf '%s\n' $FSMONITOR_LIST

View file

@ -854,6 +854,10 @@ static void set_common_push_options(struct transport *transport,
die(_("helper %s does not support --signed=if-asked"), name);
}
if (flags & TRANSPORT_PUSH_ATOMIC)
if (set_helper_option(transport, TRANS_OPT_ATOMIC, "true") != 0)
die(_("helper %s does not support --atomic"), name);
if (flags & TRANSPORT_PUSH_OPTIONS) {
struct string_list_item *item;
for_each_string_list_item(item, transport->push_options)

View file

@ -208,6 +208,9 @@ void transport_check_allowed(const char *type);
/* Filter objects for partial clone and fetch */
#define TRANS_OPT_LIST_OBJECTS_FILTER "filter"
/* Request atomic (all-or-nothing) updates when pushing */
#define TRANS_OPT_ATOMIC "atomic"
/**
* Returns 0 if the option was used, non-zero otherwise. Prints a
* message to stderr if the option is not used.

View file

@ -25,8 +25,9 @@ IPATTERN("ada",
"|=>|\\.\\.|\\*\\*|:=|/=|>=|<=|<<|>>|<>"),
PATTERNS("dts",
"!;\n"
"!=\n"
/* lines beginning with a word optionally preceded by '&' or the root */
"^[ \t]*((/|&?[a-zA-Z_]).*)",
"^[ \t]*((/[ \t]*\\{|&?[a-zA-Z_]).*)",
/* -- */
/* Property names and math operators */
"[a-zA-Z0-9,._+?#-]+"